method which throws at first and second call:
public void foo() throws Exception
test:
@test
public void testFooThrowsAtFirstAndSecondTime(){
boolean thrown;
try {
foo();
} catch (Exception e) {
thrown = true;
}
assertTrue(thrown);
thrown = false;
try {
foo();
} catch (Exception e) {
thrown = true;
}
assertTrue(thrown);
foo();
}
Could you help me find a better solution for this? Use of Mockito for a better solution would be also acceptable.
With better i mean, if i could avoid try/catch or even multiple try/catch in my test. In other languages or in jAssert i think even in spring there are statements like:
assertThrows(method(..)) //PseudoCode
I thought with Mockito or JUnit 4.x there is a similar thing.
I know about
@Test(expected=Exception)
But this would only be acceptable if i expect one throw and the test ends after that.
The key here is that the try block is crucial if you want to resume execution after an exception. You can factor it out into a method or library, but it has to be called within your test method.
Things that work:
The tried-and-true
fail()
idiom that you and nrainier cite, which I prefer:catch-exception is a library that, like Mockito, wraps the passed object and puts a try block around each method. Mockito's caveats about final methods and classes apply here too, so this won't always work.
Note that catch-exception is in "maintenance mode" because the Java 8 solution (below) is much more solid.
Any solution like
assertThrows(() -> methodThatThrows())
(Java 8) or:...in Java 6/7. Importantly, assertThrows is called before methodThatThrows, so it can invoke methodThatThrows. Thanks Stefan for pointing out Fishbowl, but you could easily write an equivalent yourself:
Things that don't work:
@Test(expected=YourException.class)
will go up the stack to thetry
block that JUnit wraps your test method in. Control never returns to the test method after that.JUnit4's
ExpectedException
@Rule looks tempting, but because it wraps the entire test method, you have to set expectations before calling the method that throws the exception.Anything that looks like
assertThrows(methodCallThatThrows())
. Java will try to get the return value out ofmethodCallThatThrows
beforeassertThrows
is ever invoked, so anytry
block there can't help.@Test(expected=Exception.class)
I don't think a one-liner per method invocation is possible.
I would write the test like this:
If you are unlucky enough to have to code for some version of java prior to 8, then you cannot do it with one line per exception.
But if you are using java 8, then you can do it as Stefan Birkner suggested.
Now, if you are unwilling to include an entire library for just one method, then here is a method that will work for you, copied from my blog
So, your test code becomes something like this:
With Java 8 you can use the Fishbowl library.
It is possible to use this library with Java 6 and 7, too. But then you have to use anonymous classes.