implements Elegance {

// Elwyn Malethan's musings on software development, mountain biking and general navel–gazing...

Articles tagged with 'jmock'

Unit testing with Commons HttpClient

I‘ve been adding some test coverage to some existing code today. This code under test uses Commons HTTP Client to fetch data from an external resource. I ran into problems with mocking/stubbing the response to the HTTP requests.

I am not the only one who has faced problems with this Http Client. In that article, Florin provides a good solution using a concrete subclass of HttpClient in order to mock it‘s behaviour. His article was very useful in helping me formulate my approach.

I use JMock for dynamic mock objects and so I was keen not to have to mix of JMock-based mocks and concrete mock objects. So my approach is to use JMock‘s custom actions to provide an implementation that populates the right values in the right way. Although, I had to use some reflective cheating to set the necessary values.

private static Action willRespondWith(final int code, final String status, final String body) {
    return new CustomAction("will respond with status: " + code +  ", and contents: " + body) {
        @Override
        public Object invoke(Invocation invocation) throws Throwable {
            final Object method = invocation.getParameter(0);

            final Field statusLine = HttpMethodBase.class.getDeclaredField("statusLine");
            statusLine.setAccessible(true);
            statusLine.set(method, new StatusLine("HTTP/1.0 " + code + " " + status)); //Although, 'OK' could be anything 

            final Method setResponseStream = HttpMethodBase.class.getDeclaredMethod("setResponseStream", InputStream.class);
            setResponseStream.setAccessible(true);
            setResponseStream.invoke(method, new ByteArrayInputStream(body.getBytes("UTF-8")));

            return code;
        }
    };
}

This is intended to be used as follows:

@Test
public void testSomeHttpStuff() throws Exception {

    jmock.checking(new Expectations() {{
        allowing(client).executeMethod(with(any(HttpMethod.class)));
        will(willRespondWith(200, "OK", "{some: 'value'}"));
    }});
        
    sendHttpRequest("http://some.server/some/resource.json");
        
}

Now I can simulate all sorts of responses from the external resource.

First published on Apr 26, 2010. Last updated on: Apr 26, 2010.

jMock 2.x more expressive than 1.x?

jMock 2.5 has been around since July this year, and 2.x for much longer, but I've only recently used the 2.x API. I was pleasantly surprised. It makes great use of Generics to allow concise creation of mock objects and improves the the ability of a developer to rely on compiler/IDE support in specifying expectations. I‘m not so sure that the new expectation format is necessarily an improvement however.

In jMock 1.x I would have expected to have to write the following code (within a JUnit test case extending MockObjectTestCase) to create a mock object, implementing an arbitrary interface called Subscriber, then using it as an argument in some production code I want to test in isolation.

Mock mockSubscriber = mock(Subscriber.class);

Publisher publisher = new Publisher();
publisher.add( (Subscriber)mockSubscriber.proxy() );

It‘s not that concise and there‘s a bunch of typing I‘d rather not be doing. More generally, I‘ve found that a major improvement that Java 1.5 brought to the party was the syntactic candy that allows far more concise, and sometimes expressive source code.

This is illustrated in the example below that uses the jMock 2.x syntax

final Subscriber subscriber = mock(Subscriber.class);

Publisher publisher = new Publisher();
publisher.add(subscriber);

No casting and no reference to to some mysterious method called ‘proxy‘. It makes more sense in terms of the developers intention (that is to create mock object) and is less verbose.

Expressiveness vs Convenience (or is it ideology vs pragmatism?)

The way in which a developer might express expectations using jMock 2.x, I‘m not so sure it‘s an improvement. Certainly not when one considers the way in which Rspec or Mocha allows one to express the same thing.

Using jMock 1.x I might have expected to express an expectation using the following form.

mockSubscriber.expects(once()).method("receive").with( eq(message) );

There are a bunch of parentheses that are in the way but, that aside, it does kind of read in a way that might be considered natural language This is great because it is easy to read, even to someone who may not be a developer. Put in another way, it means that it allows a developer to express a solution that is closer to the way one might be thinking about it. That is, without having to model the solution in terms of the constraints of the Java language – even though it is syntactically valid Java code.

jMock 2.x employs the following approach.

checking(new Expectations() {{
    oneOf (subscriber).receive(message);
}});

One major advantage of the 2.x approach is that through the use of Generics any typo‘s in relation to the method names specified in the expectation will be caught at compile-time (or in the IDE) rather than at run-time. In addition, for those using a quality IDE (A) (there‘s only one IMHO :p ) one can take advantage of code-completion. I suspect that this may have been the major motivation in implementing it in this way. It was certainly a pleasurable experience being able to make more use of the productivity features in my IDE. The 2.x approach is also far more concise, which is a virtue.

It could hardly be said that it reads in a natural way however. Whilst reading the 1.x format it almost sounds like English. Reading the 2.x example would sound like you‘re learning English, and not doing too well!

Using a more natural language

If thought of on the same time-scale as human history – and all the technologies and skills humankind has developed over the millennia – software development, and computing in general could be considered a technology still in it‘s infancy. Not just computing either! The internal combustion engine was invented over a century ago, it‘s still only 30% efficient and our cars are still propelled by it!

It is no surprise therefore that some might consider that most programming languages pose a significant productivity shortcoming, despite being the result of decades of development. They force developers to express solutions (be it a single test case or an entire application) in terms that are specific to the programming language being used. This is also true of frameworks in languages that don‘t necessarily have quite as restrictive a syntactic or runtime straitjacket. TestUnit in Ruby being a case in point when compared to Rspec.

This is why frameworks such as Rspec are such a joy to use. They allow a developer to express solutions in terms that are far more like natural language. Not by coincidence are frameworks such as this far more suited to the problem domain in which they are employed. Moreover Rspec does this all within the constraints of the Ruby syntax and specification.

The whole concept of expressing solutions using a more optimal grammar is described in far more depth and far more articulately in Sergei Dmitriev‘s article on language oriented programming. He is selling a product in this article but that‘s not a crime and it‘s interesting nonetheless.

The code examples in this article have come straight from the jMock website, where there are many more great examples of usage.

First published on Dec 5, 2008. Last updated on: Dec 30, 2009.