--When writing a test in Junit, the result or test content may not change, only the input is different.
――At that time, I found it troublesome to create one test method for one test.
--I tried using @ParameterizedTest
because it can be handled.
--When not in use
@Test
public void sample1() {
assertThat("a".length()).isEqualTo(1);
}
@Test
public void sample2() {
assertThat("b".length()).isEqualTo(1);
}
(I won't write such a test, but as a sample ...)
--When using
@ParameterizedTest
@ValueSource(strings = {"a", "b"})
public void sample(String string) {
assertThat(string.length()).isEqualTo(1);
}
Like this, you can combine multiple tests just by adding a parameter to the argument of @ ValueSource
.
There are several ways to specify the parameters, so I will introduce them below.
@ValueSource --Used when "one parameter" and "type is basic type" --How to specify arguments changes depending on the parameter type -The value specified by the argument of @ValueSource is received by the argument of the method. ――It seems that you can handle all the basic types, but here I will focus on the ones that I often use.
String
--Can handle empty and whitespace characters, but not null
--If you want to handle null, use @MethodSource
described later.
@ParameterizedTest
@ValueSource(strings = {"a", "b", "c"})
public void string(String value) {
System.out.println("string: " + value);
}
Execution result
string: 'a'
string: 'b'
string: 'c'
string: ''
string: ' '
int
@ParameterizedTest
@ValueSource(ints = {1, 2 ,3})
public void ints(int value) {
System.out.println("ints: " + value);
}
Execution result
ints: 1
ints: 2
ints: 3
@CsvSource
--Use when you want to pass multiple parameters to a method
--Parameters are described as strings, and as the name of Csv suggests, multiple parameters are combined separated by commas.
--If you specify a number, you can receive either String
or ʻint`.
@ParameterizedTest
@CsvSource({"1, val1", "2, val2", "3, val3"})
public void csv(int num, String value) { //Receive a number as an int
System.out.println("num: '" + num + "', value: '" + value + "'");
}
@ParameterizedTest
@CsvSource({"1, val1", "2, val2", "3, val3"})
public void csv(String num, String value) { //Receive a number as a String
System.out.println("num: '" + num + "', value: '" + value + "'");
}
Execution result
num: '1', value: 'val1'
num: '2', value: 'val2'
num: '3', value: 'val3'
--Can handle nulls and empty strings --By default, the leading and trailing whitespace characters are trimmed, but you can leave the leading and trailing whitespace characters by enclosing them in''.
@ParameterizedTest
@CsvSource({"Empty string, ''", "Whitespace character, ' '", "null, "})
public void csv(String type, String value) {
System.out.println(type + ": '" + value + "'");
}
Execution result
Empty string: ''
Whitespace character: ' '
null: 'null'
@EnumSource
--Can be used when you want to test based on the definition of enum class
--If you specify names
or mode
, you can do include, exclude, etc.
--mode defaults to ʻINCLUDE`
Enum class to use
enum SampleEnum {
ENUM1,
ENUM2,
ENUM3
}
All cases
@ParameterizedTest
@EnumSource(SampleEnum.class)
public void enumSource(SampleEnum value) {
System.out.println("enum: " + value);
}
Execution result
enum: ENUM1
enum: ENUM2
enum: ENUM3
include
@ParameterizedTest
@EnumSource(value = SampleEnum.class, names = {"ENUM1", "ENUM2"})
public void enumInclude(SampleEnum value) {
System.out.println("enum: " + value);
}
Execution result
enum: ENUM1
enum: ENUM2
exclude
@ParameterizedTest
@EnumSource(value = SampleEnum.class, names = {"ENUM1", "ENUM2"}, mode = EnumSource.Mode.EXCLUDE)
public void enumExclude(SampleEnum value) {
System.out.println("enum: " + value);
}
Execution result
enum: ENUM3
@MethodSource
--You can pass any class as an argument by using @MethodSource
--Define a static method that returns one of Stream, Iterable, Iterator
to pass as an argument
--As mentioned above, it can handle null
@ParameterizedTest
@MethodSource("source")
public void methodSource(String value) {
System.out.println("value: " + value);
}
public static Stream<String> source() {
return Stream.of("string1", "string2", null);
}
Execution result
value: string1
value: string2
value: null