How to Use @MethodSource in JUnit for Parameterized Tests
Use
@MethodSource in JUnit to provide a method that returns test data for parameterized tests. The method must be static and return a Stream, Iterable, or array of arguments. Annotate your test method with @ParameterizedTest and specify the data provider method name in @MethodSource.Syntax
The @MethodSource annotation specifies a factory method that supplies arguments for a parameterized test. The factory method must be static and return a Stream, Iterable, or array of arguments.
- @ParameterizedTest: Marks the test method as parameterized.
- @MethodSource("methodName"): Specifies the name of the static method that provides test data.
- Static factory method: Returns test data as
Stream<Arguments>,Iterable<Arguments>, or array.
java
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.Arguments; import java.util.stream.Stream; class ExampleTest { @ParameterizedTest @MethodSource("dataProvider") void testWithMethodSource(String input, int expected) { // test logic here } static Stream<Arguments> dataProvider() { return Stream.of( Arguments.of("apple", 5), Arguments.of("banana", 6) ); } }
Example
This example shows a parameterized test that checks the length of strings using @MethodSource. The stringLengthProvider method supplies pairs of strings and their expected lengths.
java
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.Arguments; import java.util.stream.Stream; public class StringLengthTest { @ParameterizedTest @MethodSource("stringLengthProvider") void testStringLength(String input, int expectedLength) { Assertions.assertEquals(expectedLength, input.length()); } static Stream<Arguments> stringLengthProvider() { return Stream.of( Arguments.of("hello", 5), Arguments.of("JUnit", 5), Arguments.of("test", 4) ); } }
Output
Test passed: All string length assertions succeeded.
Common Pitfalls
- Non-static factory method: The method supplying data must be static; otherwise, JUnit will fail to find it.
- Wrong return type: The factory method must return a
Stream,Iterable, or array ofArgumentsor compatible types. - Method name mismatch: The name in
@MethodSourcemust exactly match the factory method name. - Missing parameters: The test method parameters must match the types and order of the arguments provided.
java
/* Wrong: Non-static method */ @ParameterizedTest @MethodSource("data") void test(String input) { } Stream<Arguments> data() { // should be static return Stream.of(Arguments.of("test")); } /* Correct: Static method */ static Stream<Arguments> data() { return Stream.of(Arguments.of("test")); }
Quick Reference
| Annotation/Method | Purpose | Notes |
|---|---|---|
| @ParameterizedTest | Marks a test method as parameterized | Required for parameterized tests |
| @MethodSource("methodName") | Specifies the data provider method | Method must be static and return Stream/Iterable/array |
| Static factory method | Provides test arguments | Returns Stream |
| Arguments.of(...) | Wraps parameters for each test case | Use to pass multiple parameters |
Key Takeaways
Use @MethodSource with a static method returning Stream, Iterable, or array of Arguments.
Ensure the factory method name matches exactly the name in @MethodSource.
The test method parameters must match the types and order of the provided arguments.
Always annotate the test method with @ParameterizedTest to enable parameterized testing.
Common errors include non-static factory methods and mismatched method names.