Friday, June 18, 2010

Mocking Frameworks – Mockito

In order to do any kind of useful testing, you always have to make the odd Simulator or Mock object so that you don’t have to worry about the dependencies that are needed by the particular component you are trying to test.  As long as you take the time to build your code using best practices, you should be able to put your mock object in place during the test without having to change your code for deployment.  I typically use Factory classes to help me do this, but there are other patterns that you can use just as effectively.  A good rule of thumb is to always code to the interface and avoid using the ‘new’ keyword for your implementations in classes that you need to test.  A simple way to do this might be:

public final Class SomeThing {
  private SomeThing() {}
  private static ISomeThing instance;
  public static ISomeThing getInstance() {
    if ( instance == null ) {
      instance = new SpecificSomeThing();
    }
    return instance;
  }
  public static void setInstance(ISomeThing someThing) {
    instance = something;
  }
}

When I want to use an instance of ISomeThing, I just call:

final ISomeThing someThing = SomeThing.getInstance();

Assuming that you are comfortable with this idea, you’ve now decoupled your dependency ISomeThing from your code and now you can test whatever calls an ISomeThing without having to manipulate the world that your dependant ISomeThing lives in…you can simply Mock it.


Lets assume that your ISomeThing looks like this:

public interface ISomeThing {
  boolean isTheAnswer(int answer);
}

To create a Mock implementation of ISomeThing, you could create something like this:

public class MockSomeThing implements ISomeThing {
   public boolean isTheAnswer(int answer) {
      return answer == 64;
   }
}

So now before you test, you just make your factory return your Mock object instead of the regular implementation of the object.

SomeThing.setInstance(new MockSomeThing());

What will happen is that when your class uses the ISomeThing instance declared in the code by the factory class, it will return true if it is supplied with the input of 64, otherwise it will return false…(hitch-hiker metaphor intended)

public void testMock() {
  SomeThing.setInstance(new MockSomeThing());
  final ISomeThing s = SomeThing.getInstance();
  
  assertTrue(s.isTheAnswer(64));
  assertFalse(s.isTheAnswer(99));
}

The only issue is that now I have a really useless class in my code base that tells me that 64 is the answer.  If I use a mocking framework  I could do this without actually creating a mock implementation:

import static org.mockito.Mockito.*;
public void testMock(){
  final ISomeThing s = mock(ISomeThing.class);
  when(s.isTheAnswer(64)).thenReturn(true);
  assertTrue(s.isTheAnswer(64));
  assertFalse(s.isTheAnswer(99));
}

This gives me the behavior I need without actually implementing the interface.  Clean and simple.

Wednesday, June 16, 2010

How to avoid Design – The ‘*.common.util’ package

I’ve seen a lot of code that makes use of a ‘util’ package; in a limited domain, I guess I don’t really have an issue with this.  A utility package would likely contain some static classes that do things like parsing strings, formatting, sorting, certain calculations…the list is endless.  There are just some things that need to be static and available and rather than think about design, we pop it into a class called ‘StringFormatUtils’ and pop it into the util package so that we can remember to look for it in six month’s time.

The fatal flaw here is that looking for some obscure little function that worked once among a sea of formatters and parsers is just not going to happen.  Instead what is likely to happen is that the next developer that needs the function will create another version of the function and pop it into that or another utility package and eventually you end up with an unmanageable pile of odds and ends in the code base.

Instead, the developer needs to take the time to think about the problem they are trying to solve from an abstract point of view.  What is it that you are trying to do? Never mind how you intend to do it.  If you are parsing data, think about a parsing architecture, ignore the details initially and then see if you have access to someone else’s wheel that they’ve already invented.  Moving from how to what is the way to re-use code.  If you need to make your own, then build it in the abstract and put it in its own domain that can be expanded and re-used.

I vote for a complete ban on any package named ‘util’ in favor of software that is written for a specific problem domain.  If you have static analysis in your build process, I recommend a rule to root it out and eliminate it…you’ll have cleaner code.