JUnit is a popular testing framework in the Java ecosystem that simplifies writing and running tests. The @ParameterizedTest annotation in JUnit is used to run the same test with different inputs. This guide covers the basics of using the @ParameterizedTest annotation with @MethodSource to write parameterized tests in JUnit.
Table of Contents
- Introduction
- Steps to Create a JUnit Parameterized Test
- Real-World Use Case
- Conclusion
Introduction
The @ParameterizedTest annotation marks methods that should be executed multiple times with different parameters. The @MethodSource annotation is used to provide a method as the source of the parameters for the parameterized test.
Steps to Create a JUnit Parameterized Test
Step 1: Add Maven Dependency
To use JUnit in your project, you need to add the JUnit dependency to your pom.xml file. Use the latest version of JUnit 5:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.9.2</version>
<scope>test</scope>
</dependency>
Step 2: Create the Class to be Tested
Create a Java class with methods that you want to test. For example, a simple MathUtils class:
public class MathUtils {
public int add(int a, int b) {
return a + b;
}
public int subtract(int a, int b) {
return a - b;
}
}
Step 3: Create the Parameterized Test Class
Create a test class in the src/test/java directory. Use the @ParameterizedTest annotation and specify the source of the parameters using @MethodSource.
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class MathUtilsTest {
private final MathUtils mathUtils = new MathUtils();
static Stream<int[]> provideAdditionArguments() {
return Stream.of(
new int[]{1, 2, 3},
new int[]{2, 3, 5},
new int[]{3, 4, 7},
new int[]{4, 5, 9}
);
}
@ParameterizedTest
@MethodSource("provideAdditionArguments")
void testAddition(int[] args) {
int a = args[0];
int b = args[1];
int expected = args[2];
assertEquals(expected, mathUtils.add(a, b), a + " + " + b + " should equal " + expected);
}
}
In this example, the provideAdditionArguments method returns a Stream of integer arrays, each containing a set of parameters for the test. The testAddition method is annotated with @ParameterizedTest and uses @MethodSource to provide the parameter sets.
Step 4: Run the Test
You can run the test using your IDE, Maven, or Gradle.
Using an IDE:
Most IDEs, like IntelliJ IDEA and Eclipse, have built-in support for running JUnit tests. Simply right-click on your test class or method and select “Run.”
Using Maven:
If you’re using Maven, you can run your tests with the following command:
mvn test
Using Gradle:
If you’re using Gradle, you can run your tests with the following command:
gradle test
Real-World Use Case
In real-world applications, you may need to test methods with various inputs. For instance, a StringUtils class might need to be tested with different string inputs to ensure correct behavior.
Create the Class to be Tested
Create a Java class that contains business logic. For example, a StringUtils class that reverses strings:
public class StringUtils {
public String reverse(String str) {
if (str == null) {
return null;
}
return new StringBuilder(str).reverse().toString();
}
}
In this class, the reverse method reverses a given string.
Create the Parameterized Test Class
Create a test class for the StringUtils in the src/test/java directory. Use the @ParameterizedTest annotation and @MethodSource to provide different string inputs and expected results:
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class StringUtilsTest {
private final StringUtils stringUtils = new StringUtils();
static Stream<String[]> provideReverseArguments() {
return Stream.of(
new String[]{"hello", "olleh"},
new String[]{"world", "dlrow"},
new String[]{"java", "avaj"},
new String[]{"", ""},
new String[]{null, null}
);
}
@ParameterizedTest
@MethodSource("provideReverseArguments")
void testReverse(String[] args) {
String input = args[0];
String expected = args[1];
assertEquals(expected, stringUtils.reverse(input), "Reversing '" + input + "' should give '" + expected + "'");
}
}
In this test class, the provideReverseArguments method returns a Stream of string arrays, each containing a set of parameters for the test. The testReverse method is annotated with @ParameterizedTest and uses @MethodSource to provide the parameter sets.
Running the Tests
You can run the tests using your IDE, Maven, or Gradle.
Using an IDE:
Most IDEs, like IntelliJ IDEA and Eclipse, have built-in support for running JUnit tests. Simply right-click on your test class or method and select “Run.”
Using Maven:
If you’re using Maven, you can run your tests with the following command:
mvn test
Using Gradle:
If you’re using Gradle, you can run your tests with the following command:
gradle test
Conclusion
The @ParameterizedTest annotation in JUnit makes it easy to run the same test with different inputs. By using @ParameterizedTest with @MethodSource, you can ensure that your methods behave correctly with various inputs without writing multiple test cases.