How to test Exceptions and verify Mock Objects using EasyMock

Let's say you are unit testing, using EasyMock to verify the behaviour of your code under test and now you want to test that your method throws a particular exception:

@Test(expected = SQLException.class)
public void parseThrowsException() throws SQLException {
ResultSet mockResultSet = createMock(ResultSet.class);
expect(mockResultSet.next()).andThrow(new SQLException());
mockResultSet.close();

replay(mockResultSet);

ResultReporter reporter = new ResultReporter();
reporter.parse(mockResultSet);

verify(mockResultSet);
}
As you can see this is another test from my previous EasyMock post on how to use EasyMock's expect method when unit testing. We are now testing that when we call the next method it throws an SQLException (to simulate the database going down).

We expect that the next method call will throw an exception and then we are expecting that close will be called. If you run this test then you will find that it passes with green flying colours - but there's a problem, this is the implementation of the parse method:
public boolean parse(ResultSet results) throws SQLException {
return results.next();
}
As you can see it never calls the close method of the passed in ResultSet - so the test should have failed. It passes because the test has exited before it gets to verify the mock ResultSet for expected behaviour.

The way around this is to use an elegant try/finally block around the code under test like this:
try {
ResultReporter reporter = new ResultReporter();
reporter.parse(mockResultSet);

} finally {
verify(mockResultSet);
}
If you make this change to the above test then it fails as expected, now I just need to fixed the code... So you now know how to test for thrown exceptions and ensure that your mock objects are verified as well!

Technorati Tags: , , , , ,

2 comments:

Rob Baillie said...

As ever, a test hasn't passed until you've seen it fail.

Bill Comer said...

Cheers Andy. Its a funny old world. I had this very same problem on Monday but did not solve it.