Verify EasyMock Behavior When Expecting Exceptions
Posted on May 13, 2008 by Scott Leberknight
Often when writing unit tests I use EasyMock to mock dependencies of the class under test. And many times I need to test that a certain type of exception is thrown during a test. Sometimes I need both, for example I am using a mock to simulate a dependency that throws an exception and I want my test to verify the appropriate exception was indeed thrown and that the mock was called properly. In those cases, I use a simple little trick: use a try/finally block along with a JUnit "@Test(expected = FooException.class
" annotation on my test method. Voila! Now you can verify mock behavior and verify the exception was thrown at the same time. This is cleaner than using a catch block and asserting the correct exception was thrown, since you rely on JUnit to verify the exception using the "expected" attribute of the @Test annotation. For example:
@Test(expected = ThrottleException.class) public void testSomethingWithDependencies() { // Create mock Rocket mainBooster = createMock(Rocket.class); // Record behavior mainBooster.ignite(); // Simluate an invalid call to 'throttleUp' expect(rocket.throttleUp(-10000L)).andThrow(ThrottleException.class); // Replay mock replay(rocket); // Create object with dependency on mainBooster SpaceShuttle shuttle = new SpaceShuttle(rocket); // Now try to perform a 'blast off' and // verify the mock behavior was as expected try { shuttle.blastOff(); } finally { verify(rocket); } }
If instead of writing tests in Java you write them in Groovy, the above code could be a little bit Groovier, though not much. (In an earlier post I showed how you can write unit tests in Groovy and still use JUnit instead of GroovyTestCase
if you like.)
@Test(expected = ThrottleException) void testSomethingWithDependencies() { // Create mock def mainBooster = createMock(Rocket) // Record behavior mainBooster.ignite() // Simluate an invalid call to 'throttleUp' expect(rocket.throttleUp(-10000L)).andThrow(ThrottleException.class) // Replay mock replay rocket // Create object with dependency on mainBooster def shuttle = new SpaceShuttle(rocket) // Now try to perform a 'blast off' and // verify the mock behavior was as expected try { shuttle.blastOff() } finally { verify rocket } }
Even more Groovy in this case would be to extend GroovyTestCase
and use its shouldFail
method, like so:
void testSomethingWithDependencies() { // Create mock def mainBooster = createMock(Rocket) // Record behavior mainBooster.ignite() // Simluate an invalid call to 'throttleUp' expect(rocket.throttleUp(-10000L)).andThrow(ThrottleException.class) // Replay mock replay rocket // Create object with dependency on mainBooster def shuttle = new SpaceShuttle(rocket) // Now try to perform a 'blast off' and // verify the mock behavior was as expected shouldFail(ThrottleException) { shuttle.blastOff() } verify rocket }
The GroovyTestCase
version is probably the cleanest of the above three options. If you're not into Groovy, you can still use the JUnit "@Test(expected = BarException.class)
" together with a try/finally/verify in plain Java unit tests for a cleaner test experience.