Combine two jUnit test cases into one

Viewed 1786

I have the following two junit test cases:

@Test(expected=NullPointerException.class,timeout=2000)
public void X1()
{
    abc.xyz(null);
    fail("Car xyz() should throw NullPointerException when adding null items");
}

@Test(expected=NullPointerException.class,timeout=2000)
public void Y1()
{
    abc.pqr(null);
    fail("Car pqr() should throw NullPointerException when adding null items");
}

I want to combine the above two test cases into one. How should I go about it?

3 Answers

You really don't want to combine these cases into one. They're testing completely different things.

In your first test, you're testing the result of xyz with null. In your second, you're testing pqr with null. Both of these tests are fine to write and use if you want to check boundary conditions of these.

If the behavior of either method changes, in this scheme, you only rewrite one test. That is to say, if pqr suddenly becomes null-tolerant, and you have them munged together in a single test, you will still get a failure for the test since xyz isn't null-tolerant.

Keep these separate. You neither want nor need to combine these test cases together.

Using attribute expected is a very weak solution because you have no control on which instruction of the method will throw the exception.

Even if I don't understand the reason of joining them... here there are some solutions:

JUNIT4

@Test
public void xyzAndPqr(){

  try {
    abc.pqr(null);
    fail("pqr does not throw NullPointerException");
  } catch(NullPointerException npe) {};

  try {
    abc.xyz(null);
    fail("xyz does not throw NullPointerException");
  } catch(NullPointerException npe) {};

}

NOTE: the catch takes only NullPointerException so if the methods throws other kind of exception the test correctly fails

NOTE1: in the catch clause you can check additional conditions (message, cause, etc)

NOTE2: the test fails at the first not correct method without checking the remaining. to check always all methods, you can use Collector Rule .

JUNIT5

import static org.junit.jupiter.api.Assertions.*;
@Test
public void xyzAndPqr(){
   assertThrows(NullPointerException.class, () -> abc.pqr(null));
   assertThrows(NullPointerException.class, () -> abc.xyz(null));
}

NOTE: assertThrows return the effective raised Throwable in the case you need to check additional conditions (message, cause, etc)

NOTE1: the test fails at the first not correct method without checking the remaining. to always check all methods, you can use AssertAll .

import static org.junit.jupiter.api.Assertions.*;
@Test
public void xyzAndPqr(){
  AssertAll(
   () -> assertThrows(NullPointerException.class, () -> abc.pqr(null)),
   () -> assertThrows(NullPointerException.class, () -> abc.xyz(null))
  );
}   

JUNIT(both 4 and 5) with AssertJ (see http://joel-costigliola.github.io/assertj/assertj-core-features-highlight.html#exception-assertion)

import static org.assertj.core.api.Assertions.*;
@Test
public void xyzAndPqr(){
   assertThatNullPointerException().isThrownBy( () -> abc.pqr(null) );
   assertThatNullPointerException().isThrownBy( () -> abc.xyz(null) );
}

NOTE: you can use fluent syntax in assertJ: for example adding .withMessage("...")

NOTE1: the test fails at the first not correct method without checking the remaining. to check always all methods, you can use AssertAll (if in JUnit5) or assertJ soft assertions (in both cases)

Agree with Makoto that it is extremely poor to do this and flies against any sort of best practice. Also questionable why your org would care about this low a level of implementation of a unit test... anyway...

@Test
public void xyzAndPqr(){

Throwable thrown;
try{
   abc.pqr(null);
catch(Throwable e){
   thrown = e;
}

  //assert thrown
assertThat(thrown,instanceOf(NullPointerException.class));
//assert anything else, null var or create another...
thrown = null;

try{
    abc.xyz(null);
catch(Throwable e){
   thrown = e;
}

assertThat(thrown,instanceOf(NullPointerException.class));
//assert anything else

There is also some Apache ExceptionUtils within their common lib to get messages etc. if required.

If you are on Java8 the AssertJ library can handle this somewhat cleaner,

http://joel-costigliola.github.io/assertj/assertj-core-features-highlight.html#exception-assertion

  assertThatNullPointerException().isThrownBy(() -> {   abc.pqr(null); })
  assertThatNullPointerException().isThrownBy(() -> {   abc.xyz(null); })
Related