Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct way to unit test areas around exceptions

Looking at our code coverage of our unit tests we're quite high. But the last few % is tricky because a lot of them are catching things like database exceptions - which in normal circumstances just dont happen. For example the code prevents fields being too long etc, so the only possible database exceptions are if the DB is broken/down, or if the schema is changed under our feet.

So is the only way to Mock the objects such that the exception can be thrown? That seems a little bit pointless. Perhaps it's better to just accept not getting 100% code coverage?

Thanks, Dan

like image 538
Codek Avatar asked May 20 '10 11:05

Codek


People also ask

How do you handle exceptions in unit test Python?

There are two ways you can use assertRaises: using keyword arguments. Just pass the exception, the callable function and the parameters of the callable function as keyword arguments that will elicit the exception. Make a function call that should raise the exception with a context.

Which of the following is correct about a unit test case?

Q 10 - Which of the following is correct about a Unit Test Case? A - A Unit Test Case is a part of code which ensures that the another part of code (method) works as expected.


2 Answers

Usually when running into low-level exceptions, like IOException or SQLException in Java, I wrap them into a exception extending RuntimeException. I feel testing this behavior is quite important because otherwise there is the very nasty possibility of accidentally swallowing the exception.

So I do recommend testing them, if you actually do something when a low-level exception is thrown.

Edit: Added example.

public void store(User user) {
    try {
        userDao.store(user);
    } catch (IOException e) {
        // Logging, perhaps some logic.
        throw new ServiceException(e);
    }
}

@Test(expected = ServiceException.class)
public void Store_Fail() {
    UserDao userDaoMock = createMock(UserDao.class);
    User user = // Create test user.
    userDaoMock.store(user);
    replay(userDaoMock);
    userService.store(user);
    verify(userDaoMock);
}

There isn't much to test here, but if the logic requires for a ServiceException to be thrown why not test it?

like image 170
ponzao Avatar answered Oct 16 '22 13:10

ponzao


A common practice when a 100% coverage goal is specified is to cover as much code as possible by test and cover the remaining few percents by code review.

like image 30
mouviciel Avatar answered Oct 16 '22 13:10

mouviciel