Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EasyMock Exception Handling

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?

like image 776
Walls Avatar asked Dec 26 '22 08:12

Walls


1 Answers

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.

like image 190
combinatorics Avatar answered Jan 14 '23 09:01

combinatorics