Reputation: 10467
e.g, in verifySthIsSetCorrectly()
of following code, should I use assertEquals()
to check result or should I throw exception so that it is caught by try...catch
of the caller and let caller to handle?
@Parameters
public static Collection<object[]> methodParams() {
List<Object[]> params = new ArrayList<Object[]>();
/* arg, errorString */
params.add(new Object[] {"arg1", null /*errorString*/});
params.add(new Object[] {"arg2", ERROR_STRING1 /*errorString*/});
}
@Test
public void sampleTest () {
try {
MethodAndWait(arg);
assertNull("expect error String" + errorString, errorString);
} catch (Exception ex) {
assertNotNull("expect error String" + errorString, errorString);
assertTrue(ex.getMessage().contains(errorString));
}
}
private void MethodAndWait() {
call_remote_server_to_have_sth_set;
verifySthIsSetCorrectly();
}
private void verifySthIsSetCorrectly() {
int sth = getSth();
assertEquals(sth == "5");
}
Upvotes: 1
Views: 133
Reputation: 24286
I'm going to take the unusual step of adding another answer after my answer was accepted. The previous answer focused on the question raised in the summary, but I wanted to focus on the code.
I think one of the reasons why you were wondering what to do is because the test sampleTest()
is testing two completely different things. Your test method is testing normal behavior and exceptional behavior in the same test method.
Instead, split out the testing of the exceptional cases into their own test methods. For example:
@RunWith(JUnit4.class)
public class SampleTest {
@Test
public void methodAndWaitShouldAcceptNonNullValue() {
ClassUnderTest.methodAndWait("arg1")
}
@Test
public void methodAndWaitShouldThrowWhenGivenNullValue() {
try {
ClassUnderTest.methodAndWait(null);
fail("NullPointerException was not thrown");
} catch (NullPointerException ex) {
assertTrue(ex.getMessage().contains(ERROR_STRING1));
}
}
}
This has several advantages:
methodAndWait("arg1")
throws an exception, the test will fail with a useful stack tracemethodAndWait(null)
throws something other than NullPointerException
, the test will fail with a useful stack tracemethodAndWait(null)
doesn't throw anything, the test will fail with a useful messageIf you need to test with multiple arguments, you can use the Enclosed
runner:
@RunWith(Enclosed.class)
public class SampleTest {
@RunWith(Parameterized.class)
public static class WhenPassingNonNull {
@Parameters
public static Collection<object[]> methodParams() {
List<Object[]> params = new ArrayList<Object[]>();
/* arg, errorString */
params.add(new Object[] {"arg1", "result1"});
params.add(new Object[] {"arg3", "result3"});
}
public final String arg;
public final String actualResult;
public SampleTest(String arg, String actualResult) {
this.arg = arg;
this.actualResult = actualResult;
}
@Test
public void sampleTest() {
String actualResult = ClassUnderTest.methodAndWait(arg);
assertEquals(expectedResult, actualResult);
}
}
@RunWith(JUnit4.class)
public static class WhenPassingNull {
@Test
public void shouldThrowNullPointerException() {
try {
ClassUnderTest.methodAndWait(null);
fail();
} catch (NullPointerException ex) {
assertTrue(ex.getMessage().contains(ERROR_STRING1));
}
}
}
}
Upvotes: 0
Reputation: 24286
In a JUnit test, you should use assertions like assertEquals()
to verify the result of a method call or the state of an object:
@Test
public void addingTwoNumbersShouldWork() {
int result = calculator.add(5, 7);
assertEquals(12, result);
assertFalse(calculator.hasOverflow());
}
It's extremely rare to use try
and catch
in a JUnit test for anything other than testing that a code block throws an expected exception:
@Test
public void setColorShouldThrowNullPointerExceptionOnNullInput() {
try {
deathRay.setColor(null);
fail("expected NullPointerException");
} catch (NullPointerException expected) {
assertThat(expected.getMessage(), contains("death ray color"));
}
}
You do not need to use try
and catch
if the method you are testing happens to throw an exception:
@Test
public void fireDeathRay() throws DeathRayException {
deathRay.fire();
}
In the above test, if fire()
throws a DeathRayException
(or a runtime exception) the fireDeathRay
test will fail.
In JUnit4, it's even rarer to use try
and catch
, because you can use the ExpectedException
rule to check if a call throws an expected exception.
Upvotes: 4
Reputation: 24510
Your test should be
@Test
public void sampleTest () {
call_remote_server_to_have_sth_set;
int sth = getSth();
assertEquals(5, sth);
}
I would recommend to read an introduction to testing with JUnit if you haven't already done it.
Upvotes: 1