DaedTech

Stories about Software

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

JSTL Core ForEach Loop

Today, I was pleasantly surprised at how easy a time I had setting up some JSP pages to interact with my ongoing Java/Spring MVC home automation server. I seem to remember the setup for this being annoying in a past Java life, but my experience today was the opposite. So, here is a brief summary of what I did.

My plan is to install MongoDB to store the data that I’m going to use. I don’t know if this is the right choice, but it seems like a lightweight one in that I can always go “heavier” with a RDBMS later, if that seems warranted. There’s also a bit of a “let’s try it out” motivation for me in that I can add another tool to my toolbox in the process. But, that’s a task for another time (and probably another post). For now, I’m going to mimic having a persistence structure with the following java class:

Read More

By

Basic Spring MVC spring-servlet.xml Configuration

Tonight, I enjoyed a nice success. Specifically, I enjoyed the kind of success that I’ve found tends invariably to arise from using TDD — I wired some things together and discovered that everything just worked (well, at least my java code did – I did have a slight oops with javascript typos, but that’s to be expected in an environment where I get no feedback until runtime). And, what made this extra sweet is that I’m designing a server that turns lights on and off in my house. This means that at the eureka, breakthrough moment, you don’t find out from a running application or a successfully parsed file or anything as mundane as that. You’re treated to your house lighting up like a Christmas Tree to celebrate your success! (And then you’re thankful that the “off” also works because your sleeping girlfriend is probably not amused by this development.)

But, my purpose here is neither to gloat nor to stump for TDD. Instead, I wanted to give a nod to how easy it was for me to wire things up in Spring MVC 3, and what an improvement I perceive this to be from some years and versions back. Since I was doing TDD, I was basically isolating two classes that I have collaborating them and testing them individually. These classes are LightManipulationServiceHeyuImpl, which implements LightManipulationService and LightController:

public interface LightManipulationService {

	/**
	 * Turns the light in question on or off
	 * @param light - the light to toggle
	 * @param isOn - the setting (true for on, false for off)
	 * @return whether or not the operation was successful
	 */
	Boolean toggleLight(Light light, Boolean isOn);
	
	/**
	 * Change the brightness of a light
	 * @param light - the light to modify
	 * @param brightnessChange - the brightness change (positive for brighter, negative for dimmer)
	 * @return whether or not the operation succeeded
	 */
	Boolean changeBrightness(Light light, int brightnessChange);
}

public class LightManipulationServiceHeyuImpl implements LightManipulationService {

	public static final String OFF_COMMAND = "off ";

	public static final String ON_COMMAND = "on ";

	public static final String HEYU_COMMAND = "/usr/local/heyu-2.6.0/heyu ";
	
	private Runtime _runtime;
	
	/**
	 * Dependency injected constructor
	 * @param runtime - runtime to use for executing shell commands
	 */
	public LightManipulationServiceHeyuImpl(Runtime runtime) {
		if(runtime == null)
			throw new IllegalArgumentException("runtime");
		_runtime = runtime;
	}
	
	@Override
	public Boolean toggleLight(Light light, Boolean isOn) {
		try {
			String myCommand = isOn ? ON_COMMAND : OFF_COMMAND;
			return _runtime.exec(HEYU_COMMAND + myCommand + light.getLightCode()) != null;
		} catch (IOException e) {
			return false;
		}
	}

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

RequestMapping("/light")
public class LightController {

	private LightManipulationService _lightService;
	
	public LightController(LightManipulationService lightManipulationService) {
		if(lightManipulationService == null) throw new IllegalArgumentException("lightManipulationService");
		_lightService = lightManipulationService;
	}

	@RequestMapping("/light")
	public ModelAndView light() {
		return new ModelAndView();
	}

	/**
	 * Toggles the light described by room and light names on or off (command)
	 * @param room - Name of the room we find this light in
	 * @param light - Name of the light itself
	 * @param command - Whether to turn the light on or off
	 */
	@RequestMapping(value="/{room}/{light}/{command}", method=RequestMethod.PUT)
	public void toggleLight(@PathVariable String room, @PathVariable String light, @PathVariable String command) {
		_lightService.toggleLight(new Light(room, light), command.toLowerCase().equals("on"));
	}
}

This was all tested and looking good for the time being, so I figured I’d take a break from implementation and, well, see if any of it actually worked. Up until this point, I hadn’t bothered with any wireup, so I figured this would be an adventure. But, it wasn’t. A little google-fu and everything worked. I figured it would be easy enough to declare beans to do setter injection (I remembered this from the Spring MVC 1 days), but I thought that I might get snagged a little with constructor injection. I thought I might get snagged a lot with the fact that I wanted to inject the result of the static method Runtime.getRuntime() into my service.

But, I had no trouble in either case.

    
    
    
    	
    
    
    
    
    	
    

The first thing I set up was my service, using the familiar bean id and class syntax. From here, I located the constructor injection tag, but decided to come back to it since I thought the static method was going to be ugly. I then created the lightController bean and this is when I found the syntax for the constructor injection tag: constructor-arg. I specified which 0-indexed constructor argument I was supplying and referred it to my service bean. Simple enough. I don’t know whether the index is necessary with only one parameter or not, but hey, it’s working. I’ll figure that out when I need to.

From there, the static thing was surprisingly and pleasantly easy. I don’t know whether Runtime.getRuntime() is actually considered a factory method or not, but by using it in this fashion, I was able to accomplish what I wanted. This is going to come in extremely handy for cases where I have to pull things out of some framework or library static state and I don’t want to take that inline dependency to impede flexibility/testability.

And, really, that was it. I fired this up with my unit tested classes and absolutely nothing happened. I peered at the JSP pages and the javascript in them, realized I had forgotten a comma, fired again, and was dazzled by the lightshow in my house. So kudos to Spring MVC. Easy and flexible is always nice.

By

JUnit for C# 3 – Mocks and Other Niceties

Edit: It occurs to me that the name here was kind of an oops. If you’re here to see how I use JUnit while developing in C#, you’re probably going to be disappointed. I meant to title this “JUnit for C# Developers 3”, but made a rather comical omission. My apologies.

As I go along with this series of posts, I’ve come to a decision. My plan is to get my new, open source home automation server working at the level of functionality my old, struts-based one currently works. I think I’m going to muddle through TDD and posting my adventures for as long as that takes, and then I’ll probably add it to github to see if anyone wants to pull, and move on to other posting topics (like my practical design patterns series that I’ve been a little slow on lately). But, for now, I’ll keep on with these.

Goals for Today

Since my last two posts were more of a whim, I decided to get organized a little now that I’m in the swing of it. So, my goals for today’s post are the following:

  1. Find out whether or not Java now supports optional parameters.
  2. Figure out how to assert that a method throws an exception
  3. Figure out how to run a single unit test only
  4. Get setup with a mocking framework.

I figure that’s a bite-sized chunk for an hour or two, so let’s get started.

Actual Work

So, first up is Java and default parameters. The answer there seems to be a resounding “no” (it’s acquired foreach and instanceof, so I figured it was worth a shot). I saw this stackoverflow post, and upvoted the question while I was at it, but the answer seemed to be no. Given that the post was somewhat outdated, I checked around in some other places as well with the same findings. Bummer. The reason I wanted to find this out for my TDD is that I’ve adopted a pattern of doing something like this for my tests:

        /*
	 * This is here for TDD to stop me from needing to change every test
	 * if I decide to inject a xtor param
	 */
	private static LightController buildTarget(LightManipulationService service = null) {
		LightManipulationService myService = service != null ? service : new MockLightManipulationService();
		return new LightController(myService);
	}

Basically, instead of directly instantiating the class under test (CUT), I delegate that responsibility to this builder method. That way, if I decide to add a constructor parameter to the CUT, I don’t have to bother with the tiresome chore of updating all of my tests. And, adding a constructor parameter is a rather frequent occurrence for me when doing TDD.

But, it turns out that I’ll have to settle for the noisiness of a method overload to accomplish this. Perhaps its the purist in me, but I think default parameters in C# (and other languages) are a much more elegant solution to this problem than method overloads. I hate boilerplate code — it’s just more places you have to maintain and more places mistakes could be made. So, first goal accomplished, if not in a satisfying way. More on the builder and supplying an interface to the controller later.

Next up, I want to add a constructor parameter to my controller, as you may have intuited. The purpose of this light controller is to allow a user to turn lights in my house on and off with a RESTful URL scheme. The actual mechanics of lights on/off is accomplished via a shell command that invokes a driver my server is running. However, it is wildly inappropriate for a presentation layer controller to know the details of how that works, so I’m abstracting out a conceptual service:

public interface LightManipulationService {

	/**
	 * Turns the light in question on or off
	 * @param light - the light to toggle
	 * @param isOn - the setting (true for on, false for off)
	 * @return whether or not the operation was successful
	 */
	Boolean toggleLight(Light light, Boolean isOn);
	
	/**
	 * Change the brightness of a light
	 * @param light - the light to modify
	 * @param brightnessChange - the brightness change (positive for brighter, negative for dimmer)
	 * @return whether or not the operation succeeded
	 */
	Boolean ChangeBrightness(Light light, int brightnessChange);
}

“Light” is a POJO that I made to encapsulate properties for the room containing the light and the name of the light. The controller will operate by parsing the URL For the room and light parameters and then passing a corresponding light object to the service, which will take care of the actual light operations in a nod to the single responsibility principle.

Now, I want to inject an implementation of this interface into my controller and, furthermore, I want to throw an exception if a client injects null. After all, the controller for lights can’t operate in any meaningful way if it doesn’t have a service that actually does things to the lights. And this is where goal number (2) comes in. It turns out that testing for a thrown exception is pretty straightforward:

@Test(expected=IllegalArgumentException.class)
	public void constructor_Throws_Exception_On_Null_Service_Argument() {
		new LightController((LightManipulationService)null);
	}

That’s all there is to it. As an aside, I’m pretty impressed with Eclipse’s ability to take action during my TDD. For instance, when I instantiated the controller this way, I got a red won’t-compile squiggly as one would expect. As an option for fixing, I was allowed to declare a new constructor, ala CodeRush in Visual Studio (truth be told, VS may offer this too, but I’ve been using CodeRush for so long I don’t remember).

Now, my next goal was figuring out how to run an individual test, mostly for my own edification. Back to stackoverflow where I upvoted another question and answer:

In the package explorer unfold the class. It should show you all methods. Right click on the one method you want to run, then select Run As -> JUnit from the context menu (just tested with Eclipse 3.4.1). Also selecting “Run” on a single entry in the JUnit-results view to re-run a test works in the same way.

Sure enough, that did it. I can run it by right clicking the method or by highlighting it and using Ctrl-Shift-X, T. This is good enough for now, though what I’d really like is the ability that CodeRush and Visual Studio both confer to run a test with a key shortcut with my cursor inside the test. Perhaps that’ll be a goal for next time.

Now, for the meat of this post, a mocking framework. After getting that last test to pass, I now have a problem in that my code won’t compile, since I have another test that needs to inject something into the controller to get it to pass. For a mocking framework, I decided on Mockito. I chose this framework based entirely on “what did James Shore use in Let’s Play TDD”. My philosophy, generally speaking, is “get it working, optimize later”, so picking any framework and using it is better than deliberating long and hard. And, if a guy like James is using it, it’s probably worthwhile.

Installation was easy. I downloaded the jar from the download site and created a directory in my eclipse folder called “externaljars” where I placed it. I have no idea if this is a good practice or not, but a tutorial I looked at suggested creating a C:\mockito directory and I really prefer not to create clutter in root or anywhere else. Until someone tells me why not to, I’ll just stick these things in a sub-directory of Eclipse that I include in my build path.

So, next, I included this directory in my build path. 🙂 From there, I just added the mockito import and defined an overload that I mentioned while fulfilling goal (1), and I had this CUT:

@Controller
@RequestMapping("/light")
public class LightController {

	public LightController(LightManipulationService lightManipulationService) {
		if(lightManipulationService == null) throw new IllegalArgumentException("lightManipulationService");
	}

	@RequestMapping("/light")
	public ModelAndView light() {
		return new ModelAndView();
	}
}

And 4 passing tests:


package com.daedtech.daedalustest.controller;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import org.junit.Test;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.daedtech.daedalus.controller.LightController;
import com.daedtech.daedalus.services.LightManipulationService;

public class LightControllerTest {

	private static LightController buildTarget() {
		return buildTarget(null);
	}
	
	private static LightController buildTarget(LightManipulationService service) {
		LightManipulationService myService = service != null ? service : mock(LightManipulationService.class);
		return new LightController(myService);
	}
	
	@Test(expected=IllegalArgumentException.class)
	public void constructor_Throws_Exception_On_Null_Service_Argument() {
		new LightController((LightManipulationService)null);
	}
	
	@Test
	public void light_With_No_Parameters_Returns_Instance_Of_Model_And_View() {
		
		LightController myController = buildTarget();
		
		Assert.isInstanceOf(ModelAndView.class, myController.light());		
		
	}
	
	@Test
	public void light_Is_Decorated_With_RequestMapping_Annotation() throws NoSuchMethodException, SecurityException {
		
		Class myClass = LightController.class;
		Method myMethod = myClass.getMethod("light");
		Annotation[] myAnnotations = myMethod.getDeclaredAnnotations();
		
		Assert.isTrue(myAnnotations[0] instanceof RequestMapping);
	}
	
	@Test
	public void light_RequestMapping_Has_Parameter_Light() throws NoSuchMethodException, SecurityException {
		
		Class myClass = LightController.class;
		Method myMethod = myClass.getMethod("light");
		Annotation[] myAnnotations = myMethod.getDeclaredAnnotations();
		
		String myAnnotationParameter = ((RequestMapping)myAnnotations[0]).value()[0];
		
		assertEquals("/light", myAnnotationParameter);
	}
}

Now, we’re getting somewhere! This class is going to be functional pretty soon!