Verify EasyMock Behavior When Expecting Exceptions

Posted by: Scott Leberknight on 2008-05-13 13:51:00.0

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.


About Scott Leberknight

Scott Leberknight

Scott is Chief Architect at Near Infinity Corporation, an enterprise software development and consulting services company based in Reston, Virginia. He has been developing enterprise and web applications for 14 years professionally, and has developed applications using Java, Ruby, Groovy, and even an iPhone application with Objective-C. His main areas of interest include alternative persistence technologies, object-oriented design, system architecture, testing, and frameworks like Spring, Hibernate, and Ruby on Rails. In addition, Scott enjoys learning new languages to make himself a better and more well-rounded developer a la The Pragmatic Programmers' advice to "learn one language per year."

Scott holds a B.S. in Engineering Science and Mechanics from Virginia Tech, and an M. Eng. in Systems Engineering from the University of Maryland. Scott speaks at the No Fluff Just Stuff Symposiums and various other conferences. In his (sparse) spare time, Scott enjoys spending time with his wife, three children, and cat. He also tries to find time to play soccer, go snowboarding, and mountain bike whenever he can.

More About Scott »

NFJS, the Magazine

2012-04-01 00:00:00.0 Issue Now Available
  • Connected Data With Neo4J

    by Tim Berglund
  • On Prototypal Inheritance, Part 1

    by Raju Gandhi
  • Log4JFugue Part Two

    by Brian Tarbox
  • Demystifying Java-Groovy Integration

    by Venkat Subramaniam
Learn More »