Hoinzey

Javascript. Kotlin. Android. Java

JUnit: Parameterized tests

This won't go into exhaustive detail or even cover all the different ways you can use parameterized tests in JUnit. For that kind of thing, go check out the official docs or this great post from the team behind Baeldung.


I'm just going to put down examples of some of the ones I use most so when I forget how to do them, I can come back here to copy and paste.


Value Source

Using the "@ValueSource" annotation we can pass in a list of literal values. The test will be run once for each value. Notably you can't pass "null" into the test in this way but the second test below shows you how.


Annotating the test with @EmptySource or @NullSource passes in empty/null values. To make it quicker to do both they also added the @NullAndEmptySource

                    
    @ParameterizedTest
    @ValueSource(ints = {2, 18, 86, 1012})
    public void testNumbersAreEven(int in) {
        assert(NumberUtils.isEven(in));
    }

    @ParameterizedTest
    @NullAndEmptySource
    @ValueSource(strings = {" "})
    public void testNullValuesThrowException(String in) {
        assertThrows(IllegalArgumentException.class, () -> NumberUtils.isEven(in));
    }
                

Csv Source

Using the @CsvSource annotation we can do two different executions. We can pass in a single comma separated list of values which will be executed one-by-one similar to @ValueSource. We can also pass in an array of comma-separated values where the first is the input and the second is the expected output.

                    
    @ParameterizedTest
    @CsvSource({"6,18,44,1012"})
    public void testNumbersAreEven(String in) {
        assert(NumberUtils.isEven(in));
    }

    @ParameterizedTest
    @CsvSource({"the godFathEr,the_godfather","will the wOnkA,will_the_wonka"})
    public void testStringNormalization(String in, String expected) {
        assertEquals(StringUtils.normalize(in), expected);
    }
                

Method Source

Using the @MethodSource allows us to pass in more complicated objects. If you are only passing in a single value to check then you don't need to create Arguments as seen below.

                
    @ParameterizedTest
    @MethodSource("getStringsToNormalize")
    public void testStringNormalizationFromMethod(final String in, final String expected) {
        assertEquals(StringUtils.normalize(in), expected);
    }

    private static Stream<Arguments> getStringsToNormalize() {
        return Stream.of(
                Arguments.of("thE GoDFathEr", "the_godfather"), // null strings should be considered blank
                Arguments.of("thE MarVellous UnivERSE", "the_marvellous_universe")
        );
    }