EasyMock Exception Handling

12,565

Solution 1

Here's how I handle exceptions in unit tests:

If you aren't explicitly testing for the exception then you should add a throws clause to the method - if the exception was thrown and you weren't expecting it to be thrown then that's a test fail. e.g.,

@Test
public void testFooNormal() throws DBException{
    String key = "test";
    String value = "expected";
    daoClass daoMock = createMock(daoClass.class);
    expect(daoMock.lookup(key)).andReturn(value);
    // do an assert on returned value
    ...
}

If you are explicitly testing for the exception then put a try-catch around the line you expect it to be thrown from (catching the narrowest version of the Exception you expect) and then set a boolean in the catch clause and the assert should be on the value of the boolean. e.g.,

@Test
public void testFooError(){
    String key = "test";
    String value = "expected";
    boolean exceptionThrown = false;
    daoClass daoMock = createMock(daoClass.class);
    try{
      expect(daoMock.lookup(key)).andReturn(value);
    }catch (DBException e) {
      exceptionThrown = true;
    }
    // assert exceptionThrown is true
    ...
}

This is a good way to test exceptions because it means you are testing not only that the correct exception is thrown but also that it's thrown from exactly the line you expect. If you use @test(expected=...) then a different line in the test could throw that exception and the test could incorrectly pass.

Solution 2

Your DAO logic should not change based on your test . If you are expecting your DAO to throw the exception then keep it that way and test the Exception in the way you are testing .

If you are catching the exception in DAO itself to do rollback or logging etc. , then the Test Case shouldn't expect Exception as it is not a test case scenario. You may check for NULL in this case as I expect your DAO will be returning NULL .

Share:
12,565

Related videos on Youtube

Walls
Author by

Walls

Virginia Tech Computer Science grad, who programs in the Northern VA/DC area. I've been exposed to a number of technologies including: RESTful web services, API development, various WCMS, and database ETL. I love coding and the puzzles that it throws at me daily. Whenever I'm not solving code challenges, I can be found playing video games or board/card games.

Updated on June 07, 2022

Comments

  • Walls
    Walls almost 2 years

    I am creating some junit test cases using EasyMock. So far it makes sense for classes I am expecting to return POJOs, but how should I handle dealing with a DAO object that itself could throw an exception. My test case is to check for an expected exception thrown when the DAO encounters an issue. Using EasyMock I try and mock the DAO object (testing from the foo class), what is the correct way to handle the lower level DAO exception.

    An example of the classes/simple calls is below: (Assume all getters/setters/constructors are valid and present)

    public class foo{
        private daoClass dao = daoClass.getInstance();
        public String getValueFromDB(String key) throws DBException{
            return dao.lookup(key);
        }
    }
    
    public class daoClass{ //singleton DAO 
        public daoClass getInstance(){
           //singleton access here
        }
        public String lookup(String key) throws DBException{
            try{
                //DB LOGIC
            }
            catch(Exception e){
                throw new DBException(e.getMessage());
            }
        }
    }
    

    When I try and test the foo class, I want to be able to test for this DBException. How do I handle this, should I be surronding the DAO call in a try/catch (in the test), or add a throws to the test? I know expected=DBException will pass the test if that is thrown, but how syntactically should you handle any number of inner exceptions?

    Test code Example:

    @Test(expected=DBException.class)
    public void testFooError(){
        String key = "test";
        String value = "expected";
        daoClass daoMock = createMock(daoClass.class);
        try{
            expect(daoMock.lookup(key)).andReturn(value);
        } catch (DBException e){
            // ???
        }
    }
    

    What is the correct way to handle when the expect could potentially throw errors? Should the test method throw the exception, or should a try/catch be used? Is it still correct to use the expected=EXCEPTION tag on the test?

  • Walls
    Walls about 11 years
    So the bottom case is the one I am looking for (expecting the exception), so the (expected=Exception.class) should be left off in that case?
  • Walls
    Walls about 11 years
    Quick clarification on the exceptionThrown logic... do I want to be expecting this exception around the expect call to the EasyMock object, or should I be using that logic later in the test code when I'm actually using the Mock Object and wanting the catch to fire. try{ expect() } catch { DO NOTHING } ... try{foo.getValueFromDB(value)} catch (Exception e) { exceptionThrown = true;}

Related