jMock For Mocking Unit Tests

September 24, 2006 - 2 minute read -
mock-objects

Ok, so I might not exactly be on the cutting edge with this post, but I just started playing with jMock, a framework for creating Mock objects.

Mock objects are used to isolate various layers of an application by providing a fake implementation that will mimic the behavior of the real implementation but offers a deterministic behavior. It's very useful for isolating database layers as well because DB access can slow down unit tests dramatically. And if unit tests take to long then they won't get run. Like Inversion of Control (IoC), Mock Objects, can be done by hand without the use of a framework, but frameworks can make the job a lot easier.

jMock alows you to setup the methods that you want to call and define the return values for a given set of parameters. You basically script the expected calls with the return values you want. This lets you isolate classes so that you can test just a single method or class at a time thus simplifying the tests.

public class MockTester extends MockObjectTestCase {
    Mock mockOrderService;
    OrderService orderService;
      public void setUp() throws Exception {
        mockOrderService = new Mock(OrderService.class);
        orderService = (OrderService) mockOrderService.proxy();
    }
      public void testSomeServiceMethod() throws Exception {
        String orderId = "orderId";
          // The "doesOrderExist" method will be called once with the orderId parameter
        // and will return a true boolean value
        // If the method isn't called, then the mock will complain
        mockOrderService.expects(once())
            .method("doesOrderExist")
            .with(eq(orderId))
            .will(returnValue(true);
         FullfillmentService fullfillment = new FullfillmentServiceImpl(orderService);
       assertTrue(fullfillment.confirmOrder(orderId));
    }
}

One thing to realize is that by default jMock will only create proxies for interfaces. If you want to mock concrete classes, you'll need the jmock-cglib extension and the asm library so that it can create proxies of the concrete classes.

I find this sort of scripting of Mock objects very compelling. It allows you to focus on testing the behavior of a very isolated piece of code. It even allows you to test code without having written all of the dependent objects. I encourage you to check it out for yourself.