Reputation: 333
Could you tell me please, is it normal practice to write a method (example: JUnit Test) that throws an Exception, for example:
class A {
public String f(int param) throws Exception {
if (param == 100500)
throw new Exception();
return "";
}
}
private A object = new A();
@Test
public void testSomething() throws Exception {
String expected = "";
assertEquals(object.f(5), expected);
}
In fact, method f()
won't throw an exception for that parameter(5) but nevertheless I must declare that exception.
Upvotes: 18
Views: 64214
Reputation: 9576
If the method you're calling throws a checked exception yes, you'll either need a try catch or to rethrow. It's fine to do this from the test itself. There are a variety of ways to test Exception using JUnit. I've tried to provide a brief summary below:
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
/**
* Example uses Kent Beck - Test Driven Development style test naming
* conventions
*/
public class StackOverflowExample {
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Test
// Note the checked exception makes us re-throw or try / catch (we're
// re-throwing in this case)
public void calling_a_method_which_throws_a_checked_exception_which_wont_be_thrown() throws Exception {
throwCheckedException(false);
}
/*
* Put the class of the specific Exception you're looking to trigger in the
* annotation below. Note the test would fail if it weren't for the expected
* annotation.
*/
@Test(expected = Exception.class)
public void calling_a_method_which_throws_a_checked_exception_which_will_be_thrown_and_asserting_the_type()
throws Exception {
throwCheckedException(true);
}
/*
* Using ExpectedException we can also test for the message. This is my
* preferred method.
*/
@Test
public void calling_a_method_which_throws_a_checked_exception_which_will_be_thrown_and_asserting_the_type_and_message()
throws Exception {
expectedException.expect(Exception.class);
expectedException.expectMessage("Stack overflow example: checkedExceptionThrower");
throwCheckedException(true);
}
// Note we don't need to rethrow, or try / catch as the Exception is
// unchecked.
@Test
public void calling_a_method_which_throws_an_unchecked_exception() {
expectedException.expect(Exception.class);
expectedException.expectMessage("Stack overflow example: uncheckedExceptionThrower");
throwUncheckedException();
}
private void throwCheckedException(boolean willThrow) throws Exception {
// Exception is a checked Exception
if (willThrow) {
throw new Exception("Stack overflow example: checkedExceptionThrower");
}
}
private void throwUncheckedException() throws NullPointerException {
// NullPointerException is an unchecked Exception
throw new NullPointerException("Stack overflow example: uncheckedExceptionThrower");
}
}
Upvotes: 4
Reputation: 72844
Yes it is completely fine, and if it does throw the exception the test will be considered as failed.
You need to specify that the method throws an Exception
even if you know that the specific case does not (this check is done by the compiler).
In this case, what you expect is object.f(5)
returns an empty string. Any other outcome (non-empty string or throwing an exception) would result in a failed test case.
Upvotes: 11
Reputation: 2684
A JUnit-Test is meant to test a given method for correct behavior. It is a perfectly valid scenario that the tested method throws an error (e.g. on wrong parameters). If it is a checked exception, you either have to add it to your test method declaration or catch it in the method and Assert to false (if the exception should not occur).
You can use the expected
field in the @Test
annotation, to tell JUnit that this test should pass if the exception occurs.
@Test(expected = Exception.class)
public void testSomething() throws Exception {
String expected = "";
assertEquals(object.f(5), expected);
}
In this case, the tested method should throw an exception, so the test will pass. If you remove the expected = Exception.class
from the annotation, the test will fail if an exception occurs.
Upvotes: 4
Reputation: 850
You can test that the exception is launched with this:
@Test(expected = ValidationException.class)
public void testGreaterEqual() throws ValidationException {
Validate.greaterEqual(new Float(-5), 0f, "error7");
}
Upvotes: -1