JUnit Theory Tests

A Theory JUnit test is a subset of the Parameterized JUnit test feature.

It is very similar in respects to driving tests with a set of test data, except with a few differences as explained below.

  • The test class is annotated with @RunWith(Theories.class)
  • The test does not require a constructor to assign values, which reduces the code length.
  • @DataPoint and @DataPoints annotations are used to indicate that a public static variable as a source of test data.
  • @DataPoint is a single test data value same as @Parameter
  • @DataPoints is a set of test data (iterable object) same as @Parameters
  • The tests are annotated with @Theory

The following demonstrates the use of all the Theory annotations and explains the results.

import org.junit.experimental.theories.DataPoint;  
import org.junit.experimental.theories.DataPoints;  
import org.junit.experimental.theories.Theories;  
import org.junit.experimental.theories.Theory;  
import org.junit.runner.RunWith;

@RunWith(Theories.class)
public class TheoryTest {  
    @DataPoint
    public static String actionMovie = "The Expendables";

    @DataPoints
    public static String[] movieList = new String[] {
            "Star Wars",
            "The Great Escape",
            "Rambo",
            "Terminator 2",
            "A Beautiful Mind" };

    @DataPoint
    public static String comedyMovie = "Zoolander";

    @DataPoint
    public static int sizeOfMovieList = movieList.length;

    @Theory
    public void movieTest(String movie) {
        System.out.println(movie);
    }

    @Theory
    public void sizeTest(int size) {
        System.out.println(String.format(
                "Movie List Size = %d%n", size));
    }
}

The result of this test outputs the movie titles and size of the movie list.

Movie List Size = 5

The Expendables
Zoolander
Star Wars
The Great Escape
Rambo
Terminator 2
A Beautiful Mind

Theories use reflection to decide where the test data is used.

In this case the String values were used in the movieTest and the int value used in the sizeTest.

The @DataPoint values of "The Expendables" and "Zoolander" appear first before the @DataPoints movie list values even though they appear in different positions in the code.

This can be observed if the following @DataPoint is added and the test is re-run.

@DataPoint
public static String scifiMovie = "Gravity";  

The size of the movie list is 5 instead of 7 as the original movie list is not modified by the tests.

References


comments powered by Disqus