@ArgumentsSource

The last annotation aimed to specify the source of arguments for parameterized tests in JUnit 5 is @ArgumentsSource. With this annotation, we can specify a custom (and reusable in different tests) class, which will contain the parameters for the test. This class must implement the interface org.junit.jupiter.params.provider.ArgumentsProvider.

Let’s see an example. The following class implements a Jupiter parameterized test, in which the arguments source will be defined in the class CustomArgumentsProvider1:

package io.github.bonigarcia;

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

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;

class ArgumentSourceParameterizedTest {

@ParameterizedTest
@ArgumentsSource(CustomArgumentsProvider1.class)
void testWithArgumentsSource(String first, int second) {
System.out.println("Parameterized test with (String) " + first
+ " and (int) " + second);
assertNotNull(first);
assertTrue(second > 0);
}

}

This class (named CustomArgumentsProvider1) has been implemented on our side, and due to the fact that it implements the interface ArgumentsProvider, must override the method provideArguments, in which the actual definition of parameters for the test is implemented. Looking at the code of the example, we can see that this method returns a Stream of Arguments. In this example, we are returning a couple of entries in the Stream, each one with two arguments (String and int, respectively):

package io.github.bonigarcia;

import java.util.stream.Stream;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.ArgumentsProvider;

public
class CustomArgumentsProvider1 implements ArgumentsProvider {

@Override
public Stream<? extends Arguments> provideArguments(
ExtensionContext context) {
System.out.println("Arguments provider to test "
+ context.getTestMethod().get().getName());
return Stream.of(Arguments.of("hello", 1),
Arguments.of("world", 2));
}

}

Notice also that this argument has an argument of type ExtensionContext (package org.junit.jupiter.api.extension). This argument is very useful to know the context in which the test is executed. As illustrated in the screenshot here, ExtensionContext API offers different methods to find out different attributes of the test instance (test method name, display name, tags, and so on).

In our example (CustomArgumentsProvider1), the context is used to write the test method name in the standard output:

ExtensionContext API

Thus, when executing this example, we can see two tests being executed. Moreover, we can check the log trace with the test method, thanks to the ExtensionContext object inside, out ArgumentsProvider instance:

Execution of parameterized test using @ArgumentsSource

Several argument sources can be applied to the same parameterized test. In fact, this can be done in two different ways in the Jupiter programming model:

  • Using several annotation of @ArgumentsSource together with the same @ParameterizedTest. This can be done since @ArgumentsSource is a java.lang.annotation.Repeatable annotation.
  • Using the annotation @ArgumentsSources (notice the source is plural here). This annotation is simply a container for one or more @ArgumentsSource. The following class shows a simple example:
package io.github.bonigarcia;

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

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
import org.junit.jupiter.params.provider.ArgumentsSources;

class ArgumentSourcesParameterizedTest {

@ParameterizedTest
@ArgumentsSources({
@ArgumentsSource(CustomArgumentsProvider1.class),
@ArgumentsSource(CustomArgumentsProvider2.class) })
void testWithArgumentsSource(String first, int second) {
System.out.println("Parameterized test with (String) " + first
+ " and (int) " + second);
assertNotNull(first);
assertTrue(second > 0);
}

}

Supposing that the second argument provider (CustomArgumentsProvider2.class) specifies two or more sets of argument, when executing the test class there will be four test executions:

Execution of parameterized test using @ArgumentsSources
..................Content has been hidden....................

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