DaedTech

Stories about Software

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!

By

Basic Unit Testing with JUnit for C# Developers 2

Last night, I posted about my adventures with TDD in Java from a C# developer’s perspective. As I start to shake my Java rust off a bit, I’m enjoying this more and more, so I think I’ll keep this series going for at least a bit, documenting some of my trials, travails, successes and failures. I don’t know that I intend to turn this into a long-running series, but I’m hoping to throw enough up to get a test-conscious C# developer off and running with Java.

Briefly, Some Good References

So, as part of this adventure, and to get off on the right foot, I’ve been referencing some external information. James Shore has been working on his blog series, “Let’s Play TDD” for over a year now. This is an excellent idea for those trying to get familiar with TDD as a practice. For me, I’m more interested in seeing the simple mechanics of testing in Java, such as where the handiest place to put the JUnit window is. Seriously. It sounds lame, but watching video of someone unit test in Eclipse is incredibly helpful for showing me little details that I’ve been missing and wouldn’t have thought to google.

Another reference is Jakob Jenkov’s tutorial on reflection for Java annotations. If you’ll recall, I mentioned this last time and, as it turns out, this, like many thing in life is possible. So, on that note and without further ado, here’s some code!

And Now For the Code!

	@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);
	}

These are two new tests that I added. The first one reflects on the light controller class, seeing if the light() method has an annotation of type RequestAttribute. The second test takes it a step further and sees if the first value of request mapping is “/light” (this is the base URL to which I’m going to map).

And, here is the updated code that this drove:

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

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

All I added was the annotation to light(). And this, unlike the last, more contrived example, I did in true TDD fashion. At this point, I should mention that I found a stack overflow question about whether or not testing for the presence of annotations made sense. Accepted answer seemed to say that it’s fine with a couple of dissenting responses below that.

Personally, as a mild digression, I find the dissent baffling, particularly if those people are familiar with TDD. I’m looking at my light controller class, which needs an annotation to work properly within the Spring MVC framework. It doesn’t currently have one. So… case closed. If I’m following TDD in earnest, I cannot go adding this without a red test. Uncle Bob is pretty clear on this point in his three rules of TDD: “You are not allowed to write any production code unless it is to make a failing unit test pass.” Now, I fancy myself more purist than pragmatist, so the reasoning behind this that speaks to me is that this is a testable alteration I’m making to my class, so why wouldn’t I test it?

Java-Things I’ve Learned

Here are a few random things I learned during tonight’s foray into Java TDD:

  • A more traditional import for asserts is org.junit.Assert.*;
  • “import static” versus just import allows me to use static methods without a qualifying type or being a child class of the class containing the static method. This feels icky to me, like C# extension methods, but I’m grudgingly using it for now with my tests and assert (I may revert to traditional import).
  • Java has a foreach loop: (for myString : someStringArray). During my last go-round with Java, I’m pretty sure that this didn’t exist yet.
  • Java has isinstanceof keyword. For my fellow C# travelers, here is your version of if(x is Foo)

By

Basic Unit Testing with JUnit for C# Developers

As I’ve blogged previously, I’ve become increasingly dependent on TDD to the point where I’m basically addicted to the practice. I start to get nervous and twitchy if I’m writing code that isn’t driven by tests — it feels like putting a mop into a bucket of filthy water and then using it to ‘clean’. In other words, writing code without tests feels like pushing dirt around aimlessly while having no positive effect.

But, I digress. The purpose of this post today is to document my implementation of TDD in Java using JUnit, coming from two solid years of almost exclusive C# work. So, bear in mind that I may make some mistakes here or violate some best practices (and feel free to comment and correct me), but it’s my hope that I get the basics right and perhaps can help someone else going from C# to Java.

First Things First

I won’t go into a lot of detail here, but I’m using Eclipse and have set myself up for Spring development. I had created a small, working Spring web app, and I had a little code here, but wanted to test first with any new code. To do this, I followed my C#/Visual Studio instincts and went to create a separate project containing my tests. About 85% of people from a smattering of languages favored this approach in a poll by Phil Haack, and the approach earned an answer and a vote, if not top honors, on stackoverflow.

When you go this route in Eclipse, there is no JUnit project to create, so you just create a standard java project. I did this and populated it with a directory structure mirroring that of my actual application, putting the tests in the ‘same’ package as their class under test counterparts. And then, really all that was needed was to import the org.junit.Test library which, apparently, was already wherever it needed to be (I realize that this is not helpful if you don’t have it, but this really isn’t the emphasis of this post).

Onto the Tests

The first thing I did was to create a class called LightControllerTest, as I was interested in creating a LightController class. And, I need that class to have a method called light() that would return a ModelAndView. So, I created the following test:

package com.daedtech.daedalus.controller;

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

public class LightControllerTest {

	/*
	 * This should return an instance of model and view (apparently)
	 */
	@Test
	public void light_With_No_Parameters_Returns_Instance_Of_Model_And_View() {
		
		LightController myController = new LightController();
		
		Assert.isInstanceOf(ModelAndView.class, myController.light());		
		
	}
}

A few things to note here, fellow C# developers. One is that the equivalent of MSTest [TestMethod] is the java @Test annotation. This tells the test runner that this is a unit test. Another thing to note is that I’m using the spring framework’s assert, which may not be applicable if you’re not using Spring MVC. There is also JUnit’s assert available to you. I chose the Spring one because it had isInstanceOf(), which reminded me of MSTest’s “Assert.IsInstanceOfType()”.

So, with my test written and not compiling, I wrote the following code:

package com.daedtech.daedalus.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

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

	public ModelAndView light() {
		//return new ModelAndView();
		return null;
	}
}

Now, I was primed to have a red test instead of a non-compiling one, but I needed to run the test itself. In Eclipse, there are various ways of doing it, but the closest I could come to Ctrl-R, T was Alt-Shift-X, T. Good enough – that seems to scope them the way MSTest does as well, with only the one test running, even though I defined another in a different class. But, as with Visual Studio, there are a number of different ways to run the tests — from the little green “play” button dropdown, from the context menu right clicking on the project, from within the JUnit window that appears once you run the tests, etc. So, I ran the test, saw it fail, and deleted the return null line in favor of the one that would make it pass. A little contrived, I realize, but you’ll have to cut me a bit of slack as I iron out the early kinks. Later, I’ll write tests that fail before they pass — I promise.

I’ll have to play for a bit to get myself really familiar with the ins and outs, and I’ll probably follow with more posts like this. I’m also going to be muddling my way through other random issues like “is it appropriate (or even possible) to test that a method is annotated” and “is there anything like NCrunch for Java/Eclipse”? Stay tuned! πŸ™‚

By

SVN Global Ignore

This morning, I was adding a playpen I’d created of an enormous project to subversion. In my playpen, I was only editing a handful of .cs files, but I wanted to add all .cs files to my little repository. What I didn’t want to add were, obviously, outputs of the project, but other stuff that is sourced controlled in that project, like various media files and other space-suckers.

My first thought was to impose ignores on the individual directories, manually adding things to the ignore list, but that’s incredibly cumbersome in a project of this size. At this point, I remembered the SVN global ignore settings where I can have the shell simply omit stuff in my add window and show it as ignored in explorer windows (MS Windows, here, obviously).

To access it, rick click anywhere and go to TortoiseSVN->Settings. You’ll see the following, and circled is what you want to edit:

You can put extensions here with wildcards and you can, as I did, put the names of directories in here (such as bin, debug, release, etc). Once you put these in, they will be ignored by default and they will not appear in the “add” window of tortoise. You can still add them — this does not supersede actual source control. You just have to do it manually.

By

Forget Design Documents

Waterfalls Take Time

I sat in on a meeting the other day, and heard some discussion about late breaking requirements and whether or not these requirements should be addressed in a particular release of software. One of discussion participants voiced an opinion in the negative, citing as rationale that there was not sufficient time to generate a document with all of these requirements, generate a design document to discuss how these would be implemented, and then write the code according to this document.

This filled me with a strange wistfulness. I’m actually not kidding – I felt sad in a detached way that I can’t precisely explain.

The closest that I can come is to translate this normal-seeming statement of process into real work terms. The problem and reason that a change couldn’t be absorbed was because there was no time to take the requirements, transpose them to a new document, write another document detailing exactly what to do, execute the instructions in the second document, and continually update the second document when it turned out not to be prescient.

Or, more concisely, a lot of time was required to restate the problem, take a guess at how one would solve it, and then continually and exhaustively refine that guess.

I think the source of my mild melancholy was the sense that, not only was this wasteful, but it also kind of sucks the marrow out of life (and not in the good, poetic way). If we applied this approach to cooking breakfast, it would be like taking a bunch of fresh ingredients out of the fridge, and then getting in the car with them and going to the grocery store to use them as a shopping list for buying duplicate ingredients. Then, with all the shopping prepared, it’s time to go home, get out the pots and pans, roll up your sleeves and… leave the kitchen to sit at your desk for an hour or two slaving over a written recipe.

Once the recipe is deemed satisfactory in principle by your house guests, cooking would commence. This would involve flour, herbs spices, eggs, and of course — lots more writing. If you accidentally used a pinch instead of a dash, it’d be time to update the recipe as you cooked.

Kinda sucks the life right out of cooking, and it’s hard to convince yourself that things wouldn’t have gone better had you just cooked breakfast and jotted down the recipe if you liked it.

Why Do We Do This?

If you’ve never read Samuel Taylor Coleridge’s, “The Rime of the Ancient Mariner”, you’ve missed out on a rather depressing story and the origin of the idea of an “albatross around your neck” as something that you get saddled with that bogs you down.

Long story short, during the course of this poem, the main character kills an albatross that he superstitiously believes to be holding him back, only to have the thing forced around his neck as both a branding and a punishment for angering spiritual entities with some clout. During the course of time wearing the albatross, all manner of misfortune befalls the mariner.

In the world of software development, (and ignoring the portion of the story where the mariner shoots the albatross), some of our documentation seems to become our albatross. These documents that once seemed our friends are very much our curse — particularly the design document.

No longer do they help us clarify our vision of the software as it is supposed to look, but rather they serve as obligatory bottlenecks, causing us frequent rework and cruelly distracting us by whispering in our ears echoing chants of “CMMI” or “ISO”. Getting rid of them by simply ceasing to do them seems simple to the outsider, but is thoroughly impossible for us software mariners. We soldier on in our doomed existence, listlessly writing and doing our best to keep these documents up to date.

Let’s Just Not Do It

Things need not be this bleak. Here’s a radical idea regarding the design document — just don’t make one. Now, I know what you’re thinking — how are you going to have any idea what to do if you don’t lay it all out in a blueprint? Well, simple. You’ll use a combination of up-front whiteboard sketching and test driven development. These two items will result in both better documentation, and far less wasted time.

President Eisenhower once said, “Plans are nothing, planning is everything.” This philosophy applies incredibly well to software design.

Capturing your design intentions at every step of the way is truly meaningless. Source control captures the actual state of the code, so who cares what the intentions were at a given moment? These ephemeral notions of intent are best written and left on whiteboards in the offices of developers to help each other collaborate and understand the system.

Does the end-user care about this in the slightest? Of course not! Does anyone at all care about these once they become outdated? Nope. So, why capture and update them as you go?

Capture reality when you’re done, and only as much as-is required by a given stakeholder. The more you document superfluously, the more documents you have that can get out of date. And, when your docs get out of date, you have a situation worse than no documentation — lying documentation.

The other main component of this approach is test driven development. Test driven development forces the creation and continuous updating of arguably the best form of documentation there is for fellow developers: examples. As Uncle Bob points out in the three rules of TDD, the target audience is developers, and given the choice between paragraphs/diagrams and example code, developers will almost without exception choose example code. And, example code/API is exactly what the by-product of TDD is. It’s a set of examples guaranteed to be accurate and current.

And, what’s more, TDD doesn’t just provide unit tests and an accurate sample of how to use the software — it drives good design. A TDD code base tends to be modular, decoupled and flexible simply by the emergent design through the process. This means that TDD as you go is likely to provide you with every bit as good a design as you could hope to have by rubbing your crystal ball and pretending to know exactly what 200 classes are going to be necessary up front.

Is it Really that Simple?

Well, maybe, maybe not. The solution can certainly be just that simple – ceasing to do something you’re in the habit of doing is excellent at forcing change. However, the whiteboard culture and the art of TDD certainly require some conscious practice.

So, you may want to take both for a test drive before simply scrapping your diligent design documentation. But, personally, I’d say “jump in – the water’s fine!” I don’t think I’ve ever regretted not bothering with an ‘official’ design document. I’m happy to draw up documents to communicate the function of system at a given moment (instruction manuals, package diagrams, quick overviews, whatever), but creating them to be predictive of functionality and updating them from inception to the end of time… no thank you.

The documents that we create are designed to promote understanding and help communication — not to serve as time-sucking millstones around our necks that we cite as reasons for not providing functionality to users.

By the way, if you liked this post and you're new here, check out this page as a good place to start for more content that you might enjoy.