Very quick first impression of Mockito (compared to JMock)

By YopY on Tuesday 11 January 2011 21:00 - Comments (9)
Category: -, Views: 11.414

Case: An object that has a list of Command object, each Command listening to one or more String inputs (think console application). The object under test has two methods: a setCommands() method, registering a List of Commands with the object, and a commandEntered() method that takes any String input.

The commandEntered method has to do a few things:

* Clean up the entered command (trim)
* Find a command that listens to the command, using the Command object's listensTo() method
* Call the Command's execute() method, passing it the entered (cleaned) command and the application state.

Ideal case for a mock object, where the Command object gets mocked. Purpose of the mock object is to return information when called (particularly the listensTo() method), and to verify its execute() method was called with the proper arguments.

Below are two unit tests that assert the same things. Two commands are used, one Command that listens to the input, one that doesn't - this to verify the method doesn't call the execute() method on the Command that does not listen to the input. The first test is how I used to write tests, using JMock:


Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Test
public void testCommandEnteredJMock() {
    Mockery context = new Mockery();
    // objects used inside anonymous inner classes must be final.
    final Command command = context.mock(Command.class);
    // have to explicitly give the other command a name due to name clashing.
    final Command otherCommand = context.mock(Command.class, "otherCommand");
    final CommandListener commandListener = new CommandListener();
    final String actualCommandString = "test";
    String commandStringWhitespaced = "\ttest  ";
    
    // set up JMock expectations
    context.checking(new Expectations() {{
        oneOf(otherCommand).listensTo(actualCommandString); will(returnValue(false));
        oneOf(command).listensTo(actualCommandString); will(returnValue(true));
        oneOf(command).execute(actualCommandString, game);
        never(otherCommand).execute(actualCommandString, game);
    }});
    
    commandListener.setCommands(Arrays.asList(otherCommand, command));
    commandListener.commandEntered(commandStringWhitespaced);
    // jmock does not by default test if all the expectations were met.
    context.assertIsSatisfied();
}



So, tonight I went to write a unit test for the CommandListener (let's just call it that for now), and found out that in the archetype generated by Maven, Mockito was used by default instead of JMock. So, I figured why the heck not, heard lots of positive things, and just went ahead with Mockito. Turns out it's really easy to learn. Here's roughly the same unit test (or, tests the same thing) using Mockito:


Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Test
public void testCommandEnteredMockito() {
    // create mock objects.
    Command command = mock(Command.class);
    Command otherCommand = mock(Command.class);
    State programState = mock(ProgramState.class);
    String commandStringWhitespaced = "\ttest  ";
    String actualCommandString = "test";

    // set up expectations
    when(command.listensTo(actualCommandString)).thenReturn(true);
    when(otherCommand.listensTo(actualCommandString)).thenReturn(false);

    // run the methods
    CommandListener commandListener = new CommandListener();
    commandListener.setCommands(Arrays.asList(otherCommand, command));
    commandListener.commandEntered(commandStringWhitespaced);

    // Verify the right methods were called in the right manner.
    verify(command).listensTo(actualCommandString);
    verify(otherCommand).listensTo(actualCommandString);

    // verify execute method was called properly on the given command, and
    // other command is never executed.
    verify(command).execute(actualCommandString, programState);
    verify(otherCommand, never()).execute(actualCommandString, programState);
}



In terms of lines of code, there's little difference - both use about 15 loc. JMock would actually be a bit shorter (like, one line) because you'd usually have the Mockery object as a class field. You could also save a few lines by inlining the input string with whitespace. But, these are unit tests, most important of those is that they should be easy to read and comprehend. I like using variables. LOC mean nothing.

What does mean something is the amount of typing you have to do to set up either. Writing unit tests are, at least in my perception, comparable to playing an MMO - grinding like crazy. You will start to regret writing things like context.checking(new Expectations() {{}}); over and over again, even if you put them under an Eclipse template. Worse, when you accidentally run a code formatter over your unit tests, it'll turn into something like:


Java:
1
2
3
4
5
6
7
8
9
10
11
// set up JMock expectations
        context.checking(new Expectations() {
            {
                oneOf(otherCommand).listensTo(actualCommandString);
                will(returnValue(false));
                oneOf(command).listensTo(actualCommandString);
                will(returnValue(true));
                oneOf(command).execute(actualCommandString, programState);
                never(otherCommand).execute(actualCommandString, programState);
            }
        });



which is nigh-on illegible. JMock's expectations rely in part on manual formatting to be legible and make sense. I did read about people changing their syntax highlighting to hide dots and braces, turning JMock's expectations into a readable story without Java's syntax getting in the way, but that still relies on keeping a proper syntax. I'm sure you can change the formatter's rules for unit tests, though. Still, that's a lot of code.

Mockito's mock code remain completely unaltered after a test run, and, at least based on my current (and very short) experiences, are just as legible as JMock's code - maybe even better, because there's a lot less boilerplate code. Compare (in story mode):

One of command listens to actual command will return value false
One of command execute(s) actual command, program state
(assert is satisfied)

with:

When command listens to actual command, then return false
Verify command execute(s) actual command, program state

I'm kinda starting to like Mockito, really. With JMock, both expectations and 'verifications' (i.e. verify that certain methods were called) are chucked into an Expectations object. This is better separated in Mockito - tests are more clearly separated into expectations, running, and verifying stages.

I approve.

Quick tryouts: Websockets

By YopY on Sunday 9 January 2011 21:00 - Comments are closed
Category: -, Views: 3.010

So the other day I was in Hilversum with a few dozen developers at Xebia, running along with the programmers there in their bi-weekly off-duty experimentation slash competitions slash self-educating program (I recommend such an event to everyone out there, by the way), and I ended up in a team trying out WebSockets.

WebSockets is a new server / browser communication technology currently being drafted up by the W3C Web Applications Working Group, based on a proposal by Opera, whose goal is to provide two-way communication between a (web) server and a client, which usually is a web browser. WebSockets' main purpose is to provide a means for low-overhead communication, including a server taking the initiative to send a message to the browser.

This is contrary to AJAX, where the browser is the party taking the initiative. In a situation where a client would like to get real-time updates, such as in collaborative software (ex: Google Docs, Wave), this usually means the client would have to poll the server every few moments - even if there are no updates.

Before WebSockets was conceived, several methods were proposed and put in action to come up with a similar effect - Comet, Long polling, Flash sockets, and possibly even ETags, which greatly reduce the overhead and server-side processing for AJAX requests.

Anyways, at Xebia we went out to see how mature the technology was, and if it was ready to be put in use already. We used a library called Atmosphere, which provides both a server- and clientside library for WebSockets and similar technologies. Atmosphere is a promising project, I'd reckon, because it's more than just a WebSockets implementation (based on the unfinished WebSockets standard) - it provides graceful degradation based on browser and server support. So if you have a browser that doesn't have WebSockets implemented (or activated), the Atmosphere library automatically falls back to other available techniques - long polling, comet, the works.

Our experimentations weren't really successful, it seemed, but that's to blame on a few factors:

* WebSockets is not a proper standard yet. Any implementation is half at best. Same for HTML5 and similar technologies which, despite having become extremely popular last year, are still not finished.

* WebSockets have been disabled in all major non-IE browsers due to security issues uncovered early last December.

* Possibly, Atmosphere does not degrade gracefully at all times. The example we used didn't work when selecting websocket or automatic detection of used communication method, for example, whilst an echo test did work properly.

* We didn't actually spend a lot of time on it. The event was from 4 to 9, with dinner and a new year's reception in between, and a lot of time spent trying to get the example to work.

Anyways. I figured I'd just write an intro to a blog post on the Xebia App Incubator blog, but it turned out to be a bit longer than that. Without further ado, here's the actual official results and blog post on the matter:

Xebia App Incubator: Some quick experiments with web scokets using Atmosphere

Java generics - Sublist method

By YopY on Monday 3 January 2011 13:00 - Comments (5)
Category: -, Views: 4.414

Short random post.

Sometimes you have a list, and you want to retrieve a specific sublist out of that one, for example to filter out empty list elements or to get a list of values that matches a condition. You could write a method like this for every list you have - here's one to filter blank, empty or null strings out of a List of strings, for example:


Java:
1
2
3
4
5
6
7
8
9
public static List<String> filterEmptyStrings(List<String> input) {
    List<String> output = new ArrayList<String>(input.size());
    for (String s : input) {
        if (s != null && !"".equals(s.trim())) {
            output.add(s);
        }
    }
    return output;
}



This'll get tedious in the long run though, as you'll need to create a new method for every object type you want to filter in every way. Java Generics to the rescue!


Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
public interface SublistCondition<T> {
    public boolean matches(T inputObject);
}

public static <T> List<T> subList(List<T> input, SublistCondition<T> condition) {
    List<T> result = new ArrayList<T>(input.size());
    for (T value : input) {
        if (condition.matches(value)) {
            result.add(value);
        }
    }
    return result;
}



Example usage, same result as the first example:


Java:
1
2
3
4
5
6
7
public static List<String> filterEmptyStrings(List<String> input) {
    return subList(input, new SublistCondition<String>() {
        public boolean matches(String input) {
            return input != null && !"".equals(input.trim());
        }
    });
}



It's not that much less code in this example, but you could move this particular SublistCondition into a separate object, so you can use it in every place you want to filter empty strings from a list:


Java:
1
2
3
public static List<String> filterEmptyStrings(List<String> input) {
    return subList(input, ListUtils.EmptyStringSublistCondition());
}