@MethodSource

The annotation @MethodSource allows to define the name of the static method in which the arguments for the test are provided as a Java 8 Stream. For instance, in the following example, we can see a parameterized test in which the argument provider is a static method called stringProvider. In this example, this method returns a Stream of String's and therefore the argument of the test method (callled testWithStringProvider) accepts one String argument:

package io.github.bonigarcia;

import static org.junit.jupiter.api.Assertions.assertNotNull;

import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

class MethodSourceStringsParameterizedTest {

static Stream<String> stringProvider() {
return Stream.of("hello", "world");
}

@ParameterizedTest
@MethodSource("stringProvider")
void testWithStringProvider(String argument) {
System.out.println("Parameterized test with (String) argument: "
+ argument);
assertNotNull(argument);
}

}

When running the example, we can see how the test is execute twice, once per String contained in the Stream.

Execution of a parameterized test using @MethodSource and String argument provider

The type of the objects contained in the Stream is not required to be String. In fact, this type can be anything. Let's consider another example, in which @MethodSource is linked to a static method, which returns as Stream of custom objects. In this example, this type is named Person, and here it is implemented as an inner class with two properties (name and surname).

package io.github.bonigarcia;

import static org.junit.jupiter.api.Assertions.assertNotNull;

import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

class MethodSourceObjectsParameterizedTest {

static Stream<Person> personProvider() {
Person john = new Person("John", "Doe");
Person jane = new Person("Jane", "Roe");
return Stream.of(john, jane);
}

@ParameterizedTest
@MethodSource("personProvider")
void testWithPersonProvider(Person argument) {
System.out.println("Parameterized test with (Person) argument: " +
argument);
assertNotNull(argument);
}

static class Person {
String name;
String surname;

public Person(String name, String surname) {
this.name = name;
this.surname = surname;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getSurname() {
return surname;
}

public void setSurname(String surname) {
this.surname = surname;
}

@Override
public String toString() {
return "Person [name=" + name + ", surname=" + surname + "]";
}

}

}

As the following screenshot shows, when executing this example, the parameterized test is exercise twice, once per Person objects contained in the Stream ("John Doe" and "Jane Roe").

Execution of parameterized test using @MethodSource and custom object argument provider

We can also use @MethodSource to specify argument providers which contain integer primitive types, concretely of int, double, and long. The following class contains an example. We can see three parameterized tests. The first one (named testWithIntProvider) uses the annotation @MethodSource to link with the static method intProvider. In the body of this method, we use the standard Java class IntStream to return an Stream of int values. The second and third test (called testWithDoubleProvider and testWithLongProvider) are quite similar, but using a Stream of double and long values, respectively:

package io.github.bonigarcia;

import static org.junit.jupiter.api.Assertions.assertNotNull;

import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

class MethodSourcePrimitiveTypesParameterizedTest {

static IntStream intProvider() {
return IntStream.of(0, 1);
}

@ParameterizedTest
@MethodSource("intProvider")
void testWithIntProvider(int argument) {
System.out.println("Parameterized test with (int) argument: " +
argument);
assertNotNull(argument);
}

static DoubleStream doubleProvider() {
return DoubleStream.of(2d, 3d);
}

@ParameterizedTest
@MethodSource("doubleProvider")
void testWithDoubleProvider(double argument) {
System.out.println(
"Parameterized test with (double) argument: " + argument);
assertNotNull(argument);
}

static LongStream longProvider() {
return LongStream.of(4L, 5L);
}

@ParameterizedTest
@MethodSource("longProvider")
void testWithLongProvider(long argument) {
System.out.println(
"Parameterized test with (long) argument: " + argument);
assertNotNull(argument);
}

}

Thus, when executing this class, there will be six tests executed (three parameterized tests with two arguments each).

In the following screenshot, we can check this by following the traces written by each test to the standard output:

Execution of parameterized test using @MethodSource and primitive types argument provider

Finally, with regards to @MethodSource parameterized tests, it is worth it to know that the method providers are allowed to return a Stream of different types (objects or primitive types). This is very convenient for real-world test cases. For example, the following class implements a parameterized test in which the argument provider is a method returning arguments of mixed types: String and int. These parameters are injected in the test as method arguments (called first and second in the example).

package io.github.bonigarcia;

import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

class MethodSourceMixedTypesParameterizedTest {

static Stream<Arguments> stringAndIntProvider() {
return Stream.of(Arguments.of("Mastering", 10),
Arguments.of("JUnit 5", 20));
}

@ParameterizedTest
@MethodSource("stringAndIntProvider")
void testWithMultiArgMethodSource(String first, int second) {
System.out.println("Parameterized test with two arguments:
(String) "
+ first + " and (int) " + second);
assertNotNull(first);
assertNotEquals(0, second);
}
}

As usual, there will be test executions as entries contained in the Stream. In this case, there are two: "Mastertering" and 10, and then "JUnit 5" and 20.

Execution of parameterized test using @MethodSource with different types of arguments
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.244.250