До этого поста я сделал проверку исключений, выполнив это:
try {
myObject.doThings();
fail("Should've thrown SomeException!");
} catch (SomeException e) {
assertEquals("something", e.getSomething());
}
Я потратил несколько минут на обдумывание проблемы и придумал следующее (Java5, JUnit 3.x):
// Functor interface for exception assertion.
public interface AssertionContainer<T extends Throwable> {
void invoke() throws T;
void validate(T throwable);
Class<T> getType();
}
// Actual assertion method.
public <T extends Throwable> void assertThrowsException(AssertionContainer<T> functor) {
try {
functor.invoke();
fail("Should've thrown "+functor.getType()+"!");
} catch (Throwable exc) {
assertSame("Thrown exception was of the wrong type! Expected "+functor.getClass()+", actual "+exc.getType(),
exc.getClass(), functor.getType());
functor.validate((T) exc);
}
}
// Example implementation for servlet I used to actually test this. It was an inner class, actually.
AssertionContainer<ServletException> functor = new AssertionContainer<ServletException>() {
public void invoke() throws ServletException {
servlet.getRequiredParameter(request, "some_param");
}
public void validate(ServletException e) {
assertEquals("Parameter \"some_param\" wasn't found!", e.getMessage());
}
public Class<ServletException> getType() {
return ServletException.class;
}
}
// And this is how it's used.
assertThrowsException(functor);
Глядя на этих двоих, я не могу решить, какой из них мне больше нравится. Я предполагаю, что это одна из тех проблем, когда достижение цели (в моем случае, метода утверждения с параметром functor) не стоит этого в долгосрочной перспективе, поскольку сделать эти 6+ кода для утверждения попытки намного проще ..catch block.
Опять же, может быть, мой 10-минутный результат решения проблем в пятницу вечером - не самый разумный способ сделать это.