A recent question on Twitter about my JUnit Kung Fu talk got me thinking - is it possible to combine the expressivity of Hamcrest asserts with the power of parameterized testing? The answer is, of course, yes. Hamcrest expressions are not limited to assertThat statements - they can be used in isolation as well.
For example, here is a simple example of how you can use JUnit 4 parameterized tests in combination with Hamcrest matchers to match not only values, but expressions:
@RunWith(Parameterized.class)
import java.util.Arrays;
import java.util.Collection;
import org.hamcrest.Matcher;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.MatcherAssert.*;
public class ParameterizedTestWithMatchersTest {
private int value;
private Matcher expectedValue;
@Parameters
public static Collection
I've added a describeExpectations() method to make any error methods take advantage of Hamcrest's nice error reporting features:
java.lang.AssertionError: 4 should be
(a value greater than <1> and a value less than <3>)
Expected: is <true>
got: <false>
Of course, typically you would process the input data before comparing it to the expected outcome, so you would probably tailor this method to make it more relevant to the task at hand:
@RunWith(Parameterized.class)
public class ParameterizedTestWithMatchersTest {
private int value;
private Matcher expectedValue;
@Parameters
public static Collection
I'm not sure what the use case for this would be - typically I use parameterized tests with very specific expected values. But I'm sure someone will think of something ;-) .