Saturday, June 25, 2011

JUnit Theories

A Theory is slightly different from a parameterised test. A theory defines a "universal truth" which should hold in possibly infinite numbers of potential scenarios (as long as assumptions hold). For example, the statement, "if two objects are equal, then they must have the same hashcode", is a theory.

To set up a Theory in JUnit 4.4, you need to:

  • Annotate the test class with @RunWith(Theories.class)
  • Create test data using the @DataPoints or @DataPoint annotation
  • Write a method (the "theory") annotated with @Theory and accepting arguments of your data points
Example:
The example below shows a test for the Theory that if two objects are equal, they must have the same hashcode. You can define your data points in different ways as I've demonstrated below. When you run the test, the method testHashcodeEquals will be called with all possible permutations of your test data e.g. (foo,foo), (foo,bar), (foo,baz), (foo,1), (foo,2), (bar, bar), (bar, foo) etc.
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assume.assumeThat;

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 HashcodeEqualsTheory {

  @DataPoints
  public static String[] data = new String[]{"foo", "bar"};

  @DataPoint
  public static String baz = "baz";

  @DataPoints
  public static Integer[] getData(){
      return new Integer[] {1, 2};
  }

  /**
   * If two objects are equal, they must have the same hashcode
   * @param x
   * @param y
   */
  @Theory
  public void testHashcodeEquals(Object x, Object y){
      assumeThat(x.equals(y), is(true));
      assertThat(x.hashCode(), is(y.hashCode()));
  }
}
Related Posts:
Parameterized Tests in JUnit

No comments:

Post a Comment