DaedTech

Stories about Software

By

JUnit Revisited

Just as a warning, in this short post, I’m going to be writing unit tests that verify that primitives in Java do what they should and basically that gravity is still turned on. The reason for that is that I’d like to showcase some new Java unit testing goodies I’ve recently discovered since coming back into the Java fold a little here and there lately. I firmly believe that the more conversationally readable the contents of unit tests are, the more effective they will be at defining functional and internal requirements as well as showcasing the behavior of the system.

@Test
public void two_ints_are_equal() {
int x = 4;
int y = 4;
assertThat(x, is(y));
}

Coming from the .NET world and using MSTest, I’m used to semantics of Assert.AreEqual<int>(x, y) where, by convention, the “control” or expected value goes on the left and the actual value goes on the right. This is a compelling alternative in that it reads like a sentence, which is always good. The MSTest version reads “Are equal x and y” whereas this reads “x is y.” The less it reads like Yoda is talking, the better. So what enables this goodness?

import static org.junit.Assert.assertThat;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.matchers.JUnitMatchers.*;

The first import gives you assertThat(), obviously. assertThat() as shown above takes two parameters (there is an overload that takes a string as an additional parameter to let you specify a failure message): a generic type for the first parameter, and a “matcher” for the second parameter. Matchers perform evaluations on types and can be chained together in fluent fashion to allow construction of sentences that flow. For instance, you can chain the is() matcher and the not() matcher to get the following test:

@Test
public void two_ints_are_not_equal() {
int x = 4;
int y = 5;
assertThat(x, is(not(y)));
}

This really just scratches the surface and there are lots of additional matchers from hamcrest as well. You can even extend the functionality by defining your own matchers to cater to the ubiquitous language of the domain that you’re using. This just barely scratches the surface, but if you’re a java developer and haven’t given these a look, I’d suggest doing so. If you’re a .NET developer, it’s worth taking a peek at what’s going on elsewhere and perhaps defining your own such constructs if you’re feeling ambitious or looking for existing ones. In fact, if you know of good ones, please post ’em — I always like seeing what’s out there.

By

JUnit for C# Developers 8 – Obeying Demeter and Going Beyond the Tests

Last time in this series, I pulled an “Empire Strikes Back” and ended on a bit of a down note. This time around, I’d like to explore how I’ve alleviated my Law of Demeter problems, and about how fixing a code smell in my tests pushed me into a better design.

Up until now, I’ve been blogging as I go, but this one is all in the past tense — the work is done as I type this. I set out tonight with only one goal, get rid of my LOD violations, and this is where it took me.

Rethinking my Class

Recall that last time, I was passing in a database object, querying that for a collection, querying that for a cursor, and then querying the cursor for my actual database objects that I parsed and returned from the service. After a bit of trial and error and research, I decided that my service class needed to encapsulate the collection since, as best as I can tell from whatever Eclipse’s version of Intellisense is called, cursors are forward only and then you need to get another one. So, if I don’t pass in the collection at least, my service method will only work once. Fine – not thrilled about the collection.cursor.objects thing, but it’s at least pulling one LOD violation out.

I now have a handful of tests that look like this:

@Test
public void returns_room_model_with_roomName_from_database_room_key() {
	
	String myRoomName = "Rumpus Room.  Yeah, that's right.  I said Rumpus Room.";
	
	DBObject myMockDatabaseObject = mock(DBObject.class);
	Mockito.when(myMockDatabaseObject.get(RoomServiceMongoImpl.ROOM_NAME_KEY)).thenReturn(myRoomName);
	
	DBCursor myMockCursor = mock(DBCursor.class);
	Mockito.when(myMockCursor.next()).thenReturn(myMockDatabaseObject).thenReturn(myMockDatabaseObject).thenReturn(null);
	Mockito.when(myMockCursor.hasNext()).thenReturn(true).thenReturn(true).thenReturn(false);
			
	DBCollection myMockCollection = PowerMockito.mock(DBCollection.class);
	Mockito.when(myMockCollection.find()).thenReturn(myMockCursor);
	
	RoomServiceMongoImpl myService = BuildTarget(myMockCollection);
	
	assertEquals(myRoomName, myService.getAllRooms().toArray(new Room[2])[0].getRoomName());
}

and my class became:

public class RoomServiceMongoImpl implements RoomService {

	public static final String ROOM_CODE_KEY = "room_code";

	public static final String ROOM_NAME_KEY = "room";
	
	private DBCollection _collection;
	
	public RoomServiceMongoImpl(DBCollection collection) {
		_collection = collection;
	}

	@Override
	public Collection getAllRooms() {
		Collection myRooms = new ArrayList();
		
		DBCursor myCursor = _collection.find();
		while(myCursor != null && myCursor.hasNext()) {
			RoomModel myModel = buildRoomModel(myCursor.next());
			if(myModel != null)
				myRooms.add(myModel);
		}
		
		return myRooms;
	}
	
	private RoomModel buildRoomModel(DBObject roomObject) {
		Object myRoomName = roomObject.get(ROOM_NAME_KEY);
		char myRoomCode = getRoomCode(roomObject.get(ROOM_CODE_KEY));
		
		if(myRoomName != null) {
			return new RoomModel(myRoomName.toString(), null, myRoomCode);
		}
		return null;
	}

	private char getRoomCode(Object myRoomCode) {
		return myRoomCode != null && myRoomCode.toString() != null && myRoomCode.toString().length() > 0 ?
				myRoomCode.toString().charAt(0) : 0;
	}
}

A lot cleaner and more manageable following some good TDD if I do say so myself (though I may be whiffing on some finer points of the language as I’m still rusty from 2 years of mostly uninterrupted C#). I’m still not thrilled about the heavy test setup overhead, but I’ve made incremental progress.

Now, where things got interesting is in wiring this up through Spring and MongoDB. The class works in test, but I need now to figure out how to use my spring-servlet.xml to get an instance of the collection injected into my class’s constructor. I wanted to do this (1) without defining any additional code and (2) without resotring to static implementations or singletons. For (1) I’d rather leave the DB setup stuff in XML as much as possible and for (2) I try to avoid static at all costs unless there’s some compelling argument that doesn’t lean prominently on a premise of “it’s more convenient”. Static is about as flexible as a diamond.

So, here is what I did:


    
    	
    
    
    
    
    	
    
    
    
    
    	
    

I discovered that I can use factory-bean and factory-method attributes to invoke instance methods on beans that I’d created, turning their return values into other beans. I also learned that “constructor-arg” is rather unfortunately named in that it actually just translates to “arguments to the method in question”. So, in the case of the mongoDatabase bean, I’m getting it from my mongo object’s getDB() method with a string parameter of “daeadlus”. On the whole, the beans above translate to new Mongo(“192.168.2.191”).getDB(“daedalus”).getCollection(“house”) being stored in the “mongoHouseCollection” bean, which I injected into my service. When I wired and fired it, it worked perfectly the first time.

So, this post has been a little thin on actual information about JUnit (really just the denouement to my last post), but there is a nugget in here for spring wireup, and, I think the most important lesson for me is that the design benefits to TDD go beyond just code. By taking my test smell seriously, I wound up with a design where I completely factored the database setup garbage out of my code, which is clearly a good thing. Now, I’ve been around the block enough times that this would have happened regardless, but it was interesting to note that making a testability/clean-code decision and sticking to my guns teased out a macroscopic design improvement.

By

JUnit for C# Developers 7 – Law of Demeter and Temporal Mocking

Last time in this series, I posted about a good reminder of a couple of principles of good object oriented design (respecting the Law of Demeter and avoiding static method invocations as much as possible). Today, I’m going to double back on this consciously a bit to explore some more possibilities in JUnit. Don’t worry – I will fix the design in subsequent posts.

Goals

Today, I’d like to accomplish the following:

  1. Have a mock change with each invocation
  2. Mock a low of demeter violation in as little code as possible

To the Code!

If you’ve followed my last few posts, you’ve noticed that I setup MongoDB. So, logically, the next step is connecting to it with my application, and the next step after that is mocking this connection so that I can unit test the logic (well, since I’m following TDD, technically the mocking comes first). Through trial and error in a throw-away piece of code, I discovered that I could access my database as so:
Read More

By

JUnit for C# Developers 6 – Cart Before the Horse

In this post, I’d like to point out something I learned while working following yesterday’s post. In my haste to find the JUnit equivalent of MS Moles, I didn’t stop to think about what I was doing.

So, as I expanded on yesterday’s effort, I realized that my mocking of Runtime.getRuntime() didn’t seem to be working properly. As I set about trying to fix this, something dawned on me. Runtime.getRuntime() returns a Runtime object, and it’s that object’s exec(string) method that I’m interested in. So, in the code that I was trying to test, I was engaging in a double whammy of a Law of Demeter violation and inlining a static dependency.

I believe I was distracted, as I mentioned, by my desire to find C# equivalents in Java and by the general newness of what I was doing. But, this is a “teachable moment” for me. It’s easy to slip into bad habits when things are unfamiliar. It’s also easy to justify doing so. When I realized what I was doing, my first thought was “well, give yourself a break, Erik — just go with it this way until you’re more comfortable.” I then shook off that silly thought and resolved to do things right.

It’s easy to follow good design principles when you’re following a tutorial or being taught. But, it’s imperative to do it all the time so that it becomes a reflex. This includes when you’re tired late at night and just wanting to turn off your downstairs light without going downstairs (my situation now). It includes when you’re behind schedule and under the gun on a project. It includes when people are giving you a hard time. It’s always. If you practice doing it right — make it rote to do it right — then that’s what you’ll do by default.

So, humbled, here is my updated code:

Tests


@RunWith(Enclosed.class)
public class LightManipulationServiceHeyuImplTest {

	private static LightManipulationServiceHeyuImpl BuildTarget() {
		return BuildTarget(Mockito.mock(Runtime.class));
	}
	
	private static LightManipulationServiceHeyuImpl BuildTarget(Runtime runtime) {
		return new LightManipulationServiceHeyuImpl(runtime);
	}
	
	public static class constructor {
		
		/**
		 * This class makes no sense without a runtime, so don't let that happen
		 */
		@Test(expected=IllegalArgumentException.class)
		public void throws_IllegalArgumentException_when_runtime_is_null() {
			new LightManipulationServiceHeyuImpl(null);
		}
	}
	
	public static class toggleLight {
		
		/**
		 * Make sure the service is invoking the runtime's exec() to invoke heyu
		 * @throws IOException
		 */
		@Test
		public void invokes_getRuntimes_exec() throws IOException {
			
			Runtime myMock = PowerMockito.mock(Runtime.class);
			Process myProcessMock = PowerMockito.mock(Process.class);
            Mockito.when(myMock.exec(Mockito.anyString())).thenReturn(myProcessMock);
            
			LightManipulationServiceHeyuImpl myService = BuildTarget(myMock);
			myService.toggleLight(new Light("asdf", "Fdsa"), true);
			
			Mockito.verify(myMock).exec(Mockito.anyString());
		}
		
		/**
		 * If the exec works fine, then return true for successful command
		 * @throws IOException
		 */
		@Test
		public void returns_true_when_exec_does_not_throw() throws IOException {
			Runtime myMock = PowerMockito.mock(Runtime.class);
			Process myProcessMock = PowerMockito.mock(Process.class);
            Mockito.when(myMock.exec(Mockito.anyString())).thenReturn(myProcessMock);
            
			LightManipulationServiceHeyuImpl myService = BuildTarget(myMock);
			assertEquals(true, myService.toggleLight(new Light("asdf", "Fdsa"), true));
		}
		
		/**
		 * If the runtime's exec throws an exception, then this was not a successful op
		 * @throws IOException 
		 */
		@Test
		public void returns_false_When_exec_throws_exception() throws IOException {
			Runtime myMock = PowerMockito.mock(Runtime.class);
            Mockito.when(myMock.exec(Mockito.anyString())).thenThrow(new IOException());
            
			LightManipulationServiceHeyuImpl myService = BuildTarget(myMock);
			assertEquals(false, myService.toggleLight(new Light("asdf", "Fdsa"), true));
		}
		
		/**
		 * If we get a null process back, something went wrong
		 * @throws IOException
		 */
		@Test
		public void returns_false_when_exec_returns_null() throws IOException {
			Runtime myMock = PowerMockito.mock(Runtime.class);
            Mockito.when(myMock.exec(Mockito.anyString())).thenReturn(null);
            
			LightManipulationServiceHeyuImpl myService = BuildTarget(myMock);
			assertEquals(false, myService.toggleLight(new Light("asdf", "Fdsa"), true));
		}
	}
}

and class under test:

public class LightManipulationServiceHeyuImpl implements LightManipulationService {

	private Runtime _runtime;
	
	public LightManipulationServiceHeyuImpl(Runtime runtime) {
		if(runtime == null)
			throw new IllegalArgumentException("runtime");
		_runtime = runtime;
	}
	
	@Override
	public Boolean toggleLight(Light light, Boolean isOn) {
		try {
			return _runtime.exec("command") != null;
		} catch (IOException e) {
			return false;
		}
	}

	@Override
	public Boolean changeBrightness(Light light, int brightnessChange) {
		// TODO Auto-generated method stub
		return null;
	}
}

Obviously, I don’t want to execute the shell command “command”, but that’s tomorrow’s TDD. I’m happy for the evening, now that I’ve refactored an inline static Law of Demeter violation out of my design plans. 🙂

By

JUnit for C# Developers 5 – Delving Further into Mocking

Today, I’m continuing my series on unit testsing with JUnit with a target audience of C# developers.

Goals

These are today’s goals that I’m going to document:

  1. See about an NCrunch-equivalent, continuous testing tool for Eclipse and Java
  2. Testing the various complexities of the @PathVariable annotations
  3. Use mockito to perform a callback
  4. Mocking something that’s not an interface

On to the Testing

The first goal is more reconnaissance than anything else. I have come to love using NCrunch (to the point where I may make a post or series of posts about it), and I’d love to see if there is a Java equivalent. NCrunch uses extra cores on your machine to continuously build and run your unit tests as you work. The result is feedback as you type as to whether or not your changes are breaking tests. The red-green-refactor cycle becomes that much speedier for it. My research led me to this stack overflow page, and two promising leads: infinitest and ct-eclipse (presumably for “continuous testing”). I’m pleased with those leads for now, and am going to shelve this as one of the goals in a future post. Today, I just wanted to investigate to see whether or not that was an option, and then move onto concrete testing tasks.

Next up, for Spring framework, my toggleLight method’s parameters need to be decorated with the @PathVariable attribute, which apparently allows delimited strings in the Request Mapping’s value to be mapped to parameters to the method. In this fashion, I’m able to map a post request REST-style URL to a request for toggling a light. To accomplish this, I studied up and wrote the following test:

		@Test
		public void has_parameters_decorated_with_PathVariable_annotation() throws NoSuchMethodException, SecurityException {
			Class myClass = LightController.class;
			Method myMethod = myClass.getMethod("toggleLight", String.class, String.class, String.class);
			Annotation[][] myAnnotations = myMethod.getParameterAnnotations();
			
			int myCount = 0;
			for(int index = 0; index < myAnnotations.length; index++) {
				if(myAnnotations[index][0] instanceof PathVariable)
					myCount++;
			}
			
			assertEquals(3, myCount);
		}

This failed, of course, and I was able to make it pass by updating my code to:

	@RequestMapping(value="/{room}/{light}/{command}", method=RequestMethod.POST)
	public void toggleLight(@PathVariable String room, @PathVariable String light, @PathVariable String command) {
		_lightService.toggleLight(null, command.toLowerCase().equals("on"));
	}

Note the @PathVariable annotations. I'm no expert here, but as I understand it, this takes variables in the mapping's value delimeted by {} and maps them to method parameters. In order to do this, however, the parameters need this annotation. So cool, I can keep doing TDD even as I add the boilerplate for Spring MVC.

At this point, however, I want to verify that the service is being invoked with parameters that actually correspond to toggleLight's arguments. Right now, we're just hardcoding null for the light. (Between last post and this one, I did some garden variety TDD using the Mockito verify() previously available in order to resolve the logic about passing true or false to the service for the light's value). Using verify(), I can make sure that I'm not passing a null light, but I have no means of actually inspecting the light. In the C#/Moq TDD world, to get to the next step, I would use the Moq .Callback(Action) functionality. In the Mockito/Java world, this is what I found:

@Test
public void calls_service_toggleLight_with_roomName_matching_room_parameter() {
	LightManipulationService myService = mock(LightManipulationService.class);
	LightController myController = buildTarget(myService);
	String myRoom = "asdf";
	myController.toggleLight(myRoom, "fdsa", "on");
	ArgumentCaptor myLightArgument = ArgumentCaptor.forClass(Light.class);
	
	verify(myService).toggleLight(myLightArgument.capture(), anyBoolean());
	
	assertEquals(myRoom, myLightArgument.getValue().getRoomName());
}

I'm creating an ArgumentCaptor object for lights and passing captor.capture() to verify(), which seems to work some magic for populating the captor's value property with the light object passed to the service. I made this test pass, and then wrote another one for the light name, and wound up with the following code:

@RequestMapping(value="/{room}/{light}/{command}", method=RequestMethod.POST)
public void toggleLight(@PathVariable String room, @PathVariable String light, @PathVariable String command) {
	_lightService.toggleLight(new Light(room, light), command.toLowerCase().equals("on"));
}

I don't know that this counts as a callback, but it is the functionality I was looking for.

So, at this point, I'm temporarily done with the controller. Now, I want to implement the the service and have it make calls to Runtime.getRuntime.exec(). But, in order to do that, I need to be able to mock it. As you know, in C#, this is the end of the line for Moq. We can use it to mock interfaces and classes with virtual methods, but static methods and other test-killers require Moq's more powerful, heavyweight cousin: the isolation framework (e.g. Moles). So, I scurried off to see if Mockito would support this.

I did not have far to look. The Mockito FAQ offered the following as limitations of the tool: cannot mock final classes, cannot mock static methods, cannot mock final methods, cannot mock equals(), hashCode(). So, no dice there. We're going to need something else. And, almost immediately, I stumbled on PowerMock, billed as an extension to Mocktio. "PowerMock uses a custom classloader and bytecode manipulation to enable mocking of static methods, constructors, final classes and methods, private methods, removal of static initializers and more." You had me at "mocking of static methods."

So, I downloaded powermock-mockito.1.4.11-full.jar and slapped it in my externaljars directory along with Mockito. As it turns out, I needed more than just that, so I downloaded the full zip file from the site, which was in a file named "powermock-mockito-testng-1.4.11.zip". I ran into runtime errors without some of these supporting libraries. From here, I poked and prodded and experimented for a while. The documentation for these tools is not especially comprehensive, but I'm used to that in C# as well. This is what wound up working for me, as a test that my service was invoking the runtime's executable:

@RunWith(Enclosed.class)
public class LightManipulationServiceHeyuImplTest {

	private static LightManipulationServiceHeyuImpl BuildTarget() {
		return new LightManipulationServiceHeyuImpl();
	}
	
	@RunWith(PowerMockRunner.class)
	@PrepareForTest(Runtime.class)
	public static class toggleLight {
		
		/**
		 * Make sure the service is invoking the runtime's exec() to invoke heyu
		 * @throws IOException
		 */
		@Test(expected=IllegalArgumentException.class)
		public void invokes_getRuntimes_exec() throws IOException {
			LightManipulationServiceHeyuImpl myService = BuildTarget();
			
			PowerMockito.mockStatic(Runtime.class); //We're going to set the mock's exec() up to throw an exception, and expect that exception
			Runtime myMock = Mockito.mock(Runtime.class);
			
			PowerMockito.doThrow(new IllegalArgumentException()).when(myMock).exec(Mockito.anyString());
			PowerMockito.when(Runtime.getRuntime()).thenReturn(myMock);
			
			myService.toggleLight(new Light("asdf", "Fdsa"), true);
		}

...

In the first place, I'd forgotten how much I loathe java's checked exceptions, for all of the reasons I always did previously and now for a new one -- they're a headache with TDD. I mention this because I apparently need to have my test method throw that exception so that I can mock the runtime. (Not even use it -- mock it). The rest of the stuff in there, I learned by experimentation. You have to include some new annotations, and you have to setup PowerMockito to mock the static class. From there, I created a mock of what Runtime.getRuntime() returns (not surprisingly, it returns a Runtime). Then, I setup the mock Runtime to toss an exception when its exec method is called -- the one that I plan to use. I then expect this exception in the test. This is my clever (perhaps too clever) way of verifying that the exec() method is called in my class, without having tests that actually go issuing shell commands. That'd be a big bucket of fail, but I'd still like to test these classes and use TDD, so this is how it has to be.

Looking Ahead

Next time, I'll work my way through developing this service and document anything that comes up there. These mocking frameworks are new to me, so it's going to be a work in progress. I may or may not play with some of the continuous testing tools as well.