Reputation: 92026
Suppose I have a method named foo
which, for certain set of input values, is expected to complete successfully and return a result, and for some other set of values, is expected to throw a certain exception. This method requires some things to have set up before it can be tested.
Given these conditions, is it better to club success and failure tests in one test, or should I maintain these cases in separate test methods?
In other words, which of the following two approaches is preferable?
Approach 1:
@Test
public void testFoo() {
setUpThings();
// testing success case
assertEquals(foo(s), y);
// testing failure case
try {
foo(f);
fail("Expected an exception.")
} catch (FooException ex) {
}
}
Approach 2:
@Test
public void testFooSuccess() {
setUpThings();
assertEquals(foo(s), y);
}
@Test
public void testFooFailure() {
setUpThings();
try {
foo(f);
fail("Expected an exception.")
} catch (FooException ex) {
}
}
Upvotes: 2
Views: 3331
Reputation: 56467
Approach 3 (extension of 2)
@Before
public void setUpThings() {
...
}
@Test
public void testFooSuccess() {
assertEquals(foo(s), y);
}
@Test(expected=FooException.class)
public void testFooFailure() {
foo(f);
}
I's good to have focused tests that exercise just one condition at a time, so that a failed test can only mean one thing (Approach 2). And if they all use the same setup, you can move that to a common setup method (@Before
). If not, maybe it's better to think about separating related cases into different classes, so that you have not only more focused cases (methods) but also more focused fixtures (classes).
Upvotes: 3
Reputation: 15641
Best you go for approach #2.
Why:
Well when an asserts fails the rest of the method is not evaluated... so by putting the tests in 2 separate methods you are sure to at least execute both tests.. failure or not.
Not only should a unit test focus on one specific unit, it should focus on one specific behaviour of that unit. Testing multiple behaviours at once only muddies the water. Take the time to separate each behaviour into its own unit test.
Upvotes: 5
Reputation: 34367
Separate test cases as better for two reasons:
Upvotes: 1
Reputation: 6572
For me Approach 2 is preferable. Because you first test happy path and then fail condition . if some one need to test happy scenarios only you will have it.
Upvotes: 1
Reputation: 308743
I like approach #2. Separate tests are better.
I don't like how you did test 2. Here's what I'd do:
@Test(expected = FooException.class)
public void testFooFailure() {
setUpThings();
foo(f);
}
Upvotes: 2