or

Using JUnit Parameterized Annotation

It’s been a while since my last post. I thought that maybe it’s time to post some new stuff :) OK, here it is:

JUnit Parameterized Annotation

Most JUnit users doesn’t know that JUnit 4 brought (or stole from TestNG) some nice features :) One of them is Parameterized Annotation. TestNG users know that you can create @DataProviders for your test class and test your unit with different data. After JUnit 4, you can do same thing with JUnit. Let’s look at the usage with an example:

I assume that you’re aware of @RunWith annotation. If you don’t know, basically it marks the test class to be run with the runner you specified in this annotation instead of the default JUnit runner. To use the @Parameterized annotation, you must run your unit test with Parameterized.class.


@RunWith(Parameterized.class)
public class MyUnitTest {
    // ...
}

The second thing you must consider is, the method you marked with @Parameterized has to be static and should return a collection, a collection of anything that you want. And the items you add to this collection has to be passed to your Unit Test Constructor as an argument. This part is very important. Please look at the following example:


@RunWith(Parameterized.class)
public class MyUnitTest {
    private Integer testNumber;

    public MyUnitTest(Integer myTestNumber) {
        this.testNumber = myTestNumber;
    }

    @Parameterized.Parameters
    public static Collection testNumbers() {
        return Arrays.asList(1, 2, 3);
    }
}

You can add any type to this collection and return it. Just don’t forget to change the signature of constructor according to this collection. Let’s say you wanna test 2 numbers, you add a number array to this collection and change the constructor to accept 2 numbers or say you wanna test an object and the boolean result, you place this object as an argument and the boolean result to the constructor. That’s the whole trick about it.

For better understanding, I’ve created a PrimeNumberValidator and its Parameterized Unit Test. Please check it:


public class PrimeNumberValidator {
    public Boolean validate(final Integer primeNumber) {
        for (int i = 2; i < (primeNumber / 2); i++) {
            if (primeNumber % i == 0) {
                return false;
            }
        }

        return true;
    }
}

And here is the Parameterized Unit Test:


@RunWith(Parameterized.class)
public class PrimeNumberValidatorTest {
    private Integer primeNumber;
    private Boolean expectedValidation;
    private PrimeNumberValidator primeNumberValidator;

    @Before
    public void initialize() {
        primeNumberValidator = new PrimeNumberValidator();
    }

    // Each parameter should be placed as an argument here
    // Every time runner triggers, it will pass the arguments from parameters we defined
    public PrimeNumberValidatorTest(Integer primeNumber, Boolean expectedValidation) {
        this.primeNumber = primeNumber;
        this.expectedValidation = expectedValidation;
    }

    @Parameterized.Parameters
    public static Collection primeNumbers() {
        return Arrays.asList(new Object[][] {
                { 2, true },
                { 6, false },
                { 19, true },
                { 22, false }
        });
    }

    // This test will run 4 times since we have 4 parameters defined
    @Test
    public void testPrimeNumberValidator() {
        assertEquals(expectedValidation, primeNumberValidator.validate(primeNumber));
    }
}

That’s it. Hope it gives some idea about the usage of @Parameterized annotation. You can also download the source code of above example from here.



3 Responses

  1. Pavel

    Data Providers is the first thing that people learn about when explore PHP Unit framework but I’ve just realized that haven’t ever used it in JUnit yet! Thank you for rising this!

    July 13, 2009, 8:03 AM

Leave a Reply

Name (required)
Mail (required)
Website