Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why JUnit test methods need to be void?

Tags:

java

junit

I've read in lot of places that test methods should/must be void, but no one says what is the reason for this.

I found in MethodValidator the following check without comments/javadocs.

    if (each.getReturnType() != Void.TYPE) {
        errors.add(new Exception("Method " + each.getName()
                + " should be void"));
    }

So why it should be void?

like image 332
Artem Malchenko Avatar asked Jul 29 '18 08:07

Artem Malchenko


2 Answers

Ask you the reverse question : why JUnit test methods would need to be not void ?
No reason : because a test method is not designed to return a result that will be exploited by a client class.
The goal of an unit test is validating some assertions. A test runner invokes the test methods and and this is the runner that interprets any assertion failure or any exception thrown during the test execution to produce the test result.

We could wonder why tests don't return the assertion result.
But it would be a bad idea as it would be very cumbersome to write unit tests :

@Test
public AssertionResult foo(){
   Bar actualBar = foo.doThat(...);
   if (actualBar == null){
       return AssertionResult.fail("actualBar == null");
   }
}

Write something like that is really readable and straight :

@Test
public void foo(){
   Bar actualBar = foo.doThat(...);
   Assert.assertNotNull(actualBar);
}

We could also wonder why test methods cannot be invoked by other test methods such as :

@Test
public int foo(){
   Bar actualBar = foo.doThat(...);
   //...
   return intValue;
}

@Test
public void fooWithComputedInt(){
   Bar actualBar = foo.doThat(foo());
   //...
}

But this also would be not a good idea as this would couple the tests execution while unit tests execution has to be isolated from others. And it also would make the tests be executed multiple times and unit tests have to be executed as fast as possible.

So really no value to make a test method return other thing than void.

like image 104
davidxxx Avatar answered Sep 27 '22 23:09

davidxxx


This is purely a design choice. JUnit does not know about your code, so it could not do anything if your method would return something.

So either it should discard a return value, or require you to use "void" methods. The authors chose the latter option - you could argue that this slightly better because it's not confusing the reader.

Note that non-@Test methods are free to do whatever they want - they don't have this limitation.

like image 42
jurez Avatar answered Sep 27 '22 21:09

jurez