7

I'm trying to perform a parametrized JUnit 5 test, how to accomplish the following?

@ParametrizedTest
@ValueSource //here it seems only one parameter is supported
public void myTest(String parameter, String expectedOutput)

I know I could use @MethodSource but I was wondering if in my case I just need to understand better @ValueSource.

dur
  • 15,689
  • 25
  • 79
  • 125
Phate
  • 6,066
  • 15
  • 73
  • 138

4 Answers4

8

The documentation says:

@ValueSource is one of the simplest possible sources. It lets you specify a single array of literal values and can only be used for providing a single argument per parameterized test invocation.

Indeed you need to use @MethodSource for multiple arguments, or implement the ArgumentsProvider interface.

dur
  • 15,689
  • 25
  • 79
  • 125
Vangelisz Ketipisz
  • 897
  • 1
  • 7
  • 10
5

Another approach is to use @CsvSource, which is a bit of a hack, but can autocast stringified values to primitives. If you need array data, then you can implement your own separator and manually split inside the function.

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import static com.google.common.truth.Truth.assertThat;

@ParameterizedTest
@CsvSource({
    "1, a",
    "2, a;b",
    "3, a;b;c"
})
void castTermVectorsResponse(Integer size, String encodedList) {
    String[] list = encodedList.split(";");
    assertThat(size).isEqualTo(list.length);
}
dur
  • 15,689
  • 25
  • 79
  • 125
James McGuigan
  • 7,542
  • 4
  • 26
  • 29
4

You need jUnit Pioneer and the @CartesianProductTest

POM:

<dependency>
    <groupId>org.junit-pioneer</groupId>
    <artifactId>junit-pioneer</artifactId>
    <version>1.3.0</version>
    <scope>test</scope>
</dependency>

Java:

import org.junitpioneer.jupiter.CartesianProductTest;
import org.junitpioneer.jupiter.CartesianValueSource;

@CartesianProductTest
@CartesianValueSource(ints = { 1, 2 })
@CartesianValueSource(ints = { 3, 4 })
void myCartesianTestMethod(int x, int y) {
    // passing test code
}
dur
  • 15,689
  • 25
  • 79
  • 125
James McGuigan
  • 7,542
  • 4
  • 26
  • 29
0

You can also use @CsvSource with arbitrary amount of arguments:

@ParameterizedTest
@CsvSource({
        "1, a",
        "2, a,b",
        "3, a,b,c"
})
void castTermVectorsResponse(ArgumentsAccessor argumentsAccessor) {
    int size = argumentsAccessor.getInteger(0);
    List<String> list = argumentsAccessor.toList().stream().skip(1).map(String::valueOf).toList();
    assertThat(size).isEqualTo(list.size());
}
D-rk
  • 5,513
  • 1
  • 37
  • 55