Fine Grained Stub Behavior With Mockito

October 18th, 2009 by James Carr

Continuing a trend of Mockito related articles, I thought I’d blog about using another feature I recently discovered while trying to figure out how to implement fine grained behavior in mockito.

First, let me set the stage… I had a method call I was writing examples for that was a typical Castor marshal operation, which often looks something like this:

StringWriter w = new StringWriter();
marshaller.setWriter(w);
marshaller.marshal(obj);
channel.send(w.toString());

Yeah I know… it looks like shit. But sometimes APIs force that on you. Anyway, I wanted to write an example illustrating that the channel received a message that was the result of whatever marshaller wrote to the output stream, but this was a little difficult to do (but easy to do with hard coded subclasses and lots and lots of boilerplate code).

The answer comes with, well, the Answer interface. To illustrate this, let me set up an example. Given I have started a unit test that looks like this:

@RunWith(MockitoJUnitRunner.class)
public class MessageServiceTest {
	@Mock private Marshaller marshaller;
	@Mock private Channel channel;
	private MessageServiceImpl messagService;

	@Before
	public void before(){
		messagService = new MessageServiceImpl();
		messagService.setChannel(channel);
		messagService.setMarshaller(marshaller);
	}

	@Test
	public void shouldWriteMarshalledDataOutToChannel(){

	}
}

We want to be able to verify that the channel (which is a simple interface with a send(String arg) method) receives whatever String the marshaller wrote to the provided Writer. Now, because the writer is constructed in the class itself, it’s difficult to stub this out. So in order to make the writer have SOMETHING written to it, we set up an answer to be invoked both when marshaller.setWriter(..) and when the marshaller.marshall(..) method is called:

private class MarshalAnswer{
		private Writer writer;
		public Answer<Writer> respondToSetWriter(){
			return new Answer<Writer>() {
				public Writer answer(InvocationOnMock invocation) throws Throwable {
					Writer w = (Writer) invocation.getArguments()[0];
					writer = w;
					return null;
				}
			};
		}
		public Answer<Object> respondToMarshall(final String writeThis){
			return new Answer<Object>(){
				public Object answer(InvocationOnMock invocation)
						throws Throwable {
					writer.write(writeThis);
					return null;
				}
			};
		}
	}

Bleh… lots and lots of boilerplate code because of the interfaces, but oh well. Here’s the revised test case in action:

@RunWith(MockitoJUnitRunner.class)
public class MessageServiceTest {
	@Mock private Marshaller marshaller;
	@Mock private Channel channel;
	private MessageServiceImpl messageService;
	private Invoice invoice;
	private MarshalAnswer answers;
	@Before
	public void before(){
		messageService = new MessageServiceImpl();
		messageService.setChannel(channel);
		messageService.setMarshaller(marshaller);
		invoice = new Invoice();
		answers = new MarshalAnswer();
	}

	@Test
	public void shouldWriteMarshalledDataOutToChannel() throws Exception{
		doAnswer(answers.respondToSetWriter()).when(marshaller).setWriter(any(Writer.class));
		doAnswer(answers.respondToMarshall("<someresult/>")).when(marshaller).marshal(invoice);

		messageService.send(invoice);

		verify(channel).send("<someresult/>");
	}
...

I could have just created the respondTo methods in the TestCase itself, but I wanted to keep it separated by putting it in a helper class.

So now we run the test and we should see the following:

Fair enough… lets add the following code to the method we’re describing and rerun:

public void send(Invoice invoice) throws Exception{
		StringWriter writer = new StringWriter();
		marshaller.setWriter(writer);
		marshaller.marshal(invoice);
		channel.send(writer.getBuffer().toString());
	}

We rerun and sure enough, green bar! The way it works is pretty simple… whenever setWriter gets invoked, the Answer object gets called and the argument is available within it (in this case the writer) which we can then store to use for the marshal call. When marshal gets called, our Answer we defined gets called and writes whatever we told it to.

While this does provide us with a useful tool when requiring some slightly complex behavior in our collaborator interactions (in this case, we essentially needed to capture what was passed to the writer, which was acting as a hidden output variable) I’d still recommend avoiding them when you can. :)

Dependency Injection is Not Just For Testing!

August 30th, 2009 by James Carr

Something I have heard in the past is the bemoaning about injecting a dependency just for the sole sake of being able to test the use of that dependency, and while reading email today I saw that someone built a “handy utility” for replacing dependencies without having to make a setter or constructor. While they saw this as a great way to bypass code created “just for testing” I disagree on the reason that Test just quite simply are not Tests.

When you are doing Test Driven Design (note that I didn’t say Development) you are not just creating an exhaustive suite of unit tests to test your code and you’re not “testing everything that could break”, if you are you are doing it wrong. Rather, by test driven design you are describing your design… you are describing the API, how it behaves, how it works. Most importantly, you are using your tests as examples of how the system under test works in a given situation and using the examples to drive how your system is designed!

As such, using Inversion of Control or Dependency Injection to provide the dependencies to your System Under Test is in no way, shape or form creating needless test code… I will tell you right now that if you are creating protected setters to inject dependencies you are misunderstanding Dependency Injection and need to re-read up on it a bit. The way I see it you should have a system that is composed of two kinds of objects… objects that have new littered all over to create objects and objects that do things (sometimes with dependencies provided to them). With this being the case, you don’t want objects that do things and have the new keyword all over the place.

I’ve seen a lot of code written that uses multiple constructors, one that takes a dependency and one no-arg constructor that creates the dependencies it needs itself. This is a general example of code that one might complain is playing lip service to the tests around it, but my solution is do away with the no-arg constructor. You’re injecting at the wrong level. Either do one of the following:

  • Use a Dependency Injection framework like Guice, Spring, or PicoContainer
  • Push the dependency creation to the client
  • Organize code into modules, with the module definitions creating and wiring the dependencies

Just my random thoughts on it… with all the confusion of Test Driven Development being focused on Testing, you can see why I’ve been really preferring Behavior Driven Development for the aspects that BDD is often called “TDD Done Right”.

Dependency Injection is about design, which happens to make you design easier to decouple from dependencies and therefore easier to provide Mocks,Stubs,Fakes,or Spies to describe how the system uses those dependencies.

Damaged

February 13th, 2008 by James Carr

Sometimes life has a way of punching you in the gut when you least expect it, irreversibly changing your life forever. This morning I woke up and flipped open my laptop as usual for my morning RSS feed reeding to discover the screen was completely frozen, with the clock stopped at 3:20am… letting me know when the disaster had occurred. A reboot simply returned a cryptic “Grub Error 17″ and discontinued booting.

Anyhow, after running a few diagnostic tools from a boot disc utility my fears have been confirmed. My hard drive is dead. This is quite disappointing, as I didn’t quite expect it to happen on a laptop so new. Unfortunately, I have lost:

  • Basically any code I have written since September, which includes a ton of AOP exercises, Scala examples, a funtime app I’ve been writing to run on Android, and quite a few other personal projects
  • 10 Gigs worth of photos I hadn’t bothered uploading to flickr yet
  • Notes and audio clips from Agile2007
  • Documents and information on houses I’m currently looking at

I can kind of live with most of these being now lost, except for the code. Not only was some of it for personal development time projects in progress, but there were a lot of projects on my laptop that I was actively learning new things with. Arrggghh!!! :(

Anyhow, anyone have any idea where to find a new hard dive for a Sony Vaio PCG-6J1L?

My Geek New Years Resolutions

January 12th, 2008 by James Carr

Of course, my main resolution this year is to undo the 50 to 60 pounds I put on over the course of 2007 (it’s troubling when you increase your pants size by 8 sizes!), but in addition to that I have several goals for 2008 that I hope to accomplish. So, here they are, in no particular order:

  • Learn Scala
  • Become a complete expert at Struts 2
  • Be a major advocate for adopting aspect oriented programming
  • Facilitate the adoption of Spring
  • Integrate at least one scripting language (Jython, JRuby, Groovy, Javascript) into an existing java system in a way that makes sense
  • Be more active in the blogsphere
  • Post more tutorials

Scala has just captured my interest a little. For those unfamiliar, here’s a quick snippet to whet your appetite:

/* Adding ! as a method on int's */
object extendBuiltins extends Application {
  def fact(n: Int): BigInt =
    if (n == 0) 1 else fact(n-1) * n
  class Factorizer(n: Int) {
    def ! = fact(n)
  }
  implicit def int2fact(n: Int) = new Factorizer(n)

  println("10! = " + (10!))
}

The last item on the list is a big goal to shoot for…. I have a ton of tutorials I’ve been asked to write, but for some reason I just haven’t gotten around to it. But I will this year, I promise.

Fear

October 16th, 2007 by James Carr

Fear is quite obviously the worst emotion that any developer (agile or not) can succumb to… the fear to try new technologies, the fear to try something out, the fear to speak up, etcetera etcetera. The list goes on. In my honest opinion, fear is the one driving force that can break a development team and cost stakeholders time and money.

The fear to just “try it and see” would have to be the biggest one… and possibly the one I think is a root problem of any software development effort. We do “spikes” in XP for this very reason… so we can try something out and see how long it would take before giving our customer an estimate. Maybe it’s just easier than we thought it was, maybe not… either way, to just simply “try it and see” we are able to confidently tell our customers “X feature will probably be about 2 units of work” rather than muttering to ourselves “I have no idea how much work that could be, but it’s probably a lot!” and telling the customer that “X feature would probably be 12 units, just to be safe.” Argh… those large unit cards of uncertainty! :)

Some may take a different route… rather than trying something different, they’ll stick with what they know. This can be fine most of the time, except in the case where “stick with what you know” is shoehorned ad nauseam to the point of ridiculousness. How many times have you came across a nice 20 branch if-else if statement (okay, it’s rare, but it can be observed)? Or rather than investigating pre-made solutions to technical problems cross cutting a program, one might instead opt to “roll their own.” Sure, inventing your own custom made low level logging system is fun, but is it really giving the customer their most value? Of course, there DO exist cases where you may need a custom logging system, but just for the sake of the argument. In short, you should stick to what you know if it’s reasonable, but don’t be afraid to think out of the box and try something different. A programming problem could take a pair an hour that might take another full team days (or even weeks) depending how the problem is approached! If you find an alternative approach to solving a problem, just try it and see!

Finally, never ever ever be afraid to speak up. If your team is making a decision you disagree with, speak up! If they disagree with you, make sure you convey the information behind the “why” you disagree with them. Further, make sure you always participate with your customers… ask questions when they meet with you, be inquisitive, collaborate. If you ever have doubts or questions about a particular story or feature, never be afraid to get them on the line… I think in the end they’d rather you “bothered” them for a few minutes than build the wrong thing. Of course, if they consider your calls “bothering them”, you might have other issues. ;)

I guess what I’m getting at in this long post is that every developer should champion courage as one of their traits… a successful developer is fearless… unafraid of change, unafraid of new technologies, unafraid to try something different out, and unafraid of any doubts in their mind.

Remember… do what you think is right, have courage, and above all, don’t let fear rule your development decisions. ;)

This is Just Depressing

June 13th, 2006 by James Carr

This evening I was browsing some of the recent posts on the amsuing thedailywtf.com and was amused by a post that detailed a certain programmer’s predecessor’s trials and tribulations trying to fulfill the requirement to”programmatically send an email in .NET” and the source control log that details the programmer’s frustration of trying to send an email under windows 2003 by programmatically manipulating Microsoft Outlook.

Yes. Manipulating the UI of Microsoft Outlook to send an email. From .NET. :(

But it doesn’t end there, the programmer has a difficult time getting around Outlook’s “anti-hijacking feature” that prompts the user to click yes if they want to let the program send the email. So he goes back and forth to the drawing board, struggles with a custom coded attempt to trick Outlook, then finally reveals the solution:

2004-12-07 16:22 — Install, on the server, a newly purchased program called ClickYes that automatically clicks “Yes” to those dialogs.

After I stopped laughing, I did a little google seatch and discovered, yes, there IS a program called ClickYes! And it’s at version 2.2! I really couldn’t stop grinning, especially when I saw the hundred dollar server license fee and the fact that it also has an API hints that sadly a lot of people have used this as a “solution” to their “problem” of programmatically sending an email.

If only he had spent a second to use google. :D

Google Spreadsheet isn’t the first?

June 8th, 2006 by James Carr

Yesterday I was pretty amazed when I got to take a look at google’s newest web application, an online spreadsheet program. what really interested me though was when I was viewing some blogs I commonly read and I stumbled upon zohosheet, a very cool online spreadsheet program written completely in javascript on the client end and also allows users to upload and view excel files.

Pretty nifty. And without the silly invite only crud.