0
0
JunitHow-ToBeginner ยท 4 min read

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 of Arguments or compatible types.
  • Method name mismatch: The name in @MethodSource must 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/MethodPurposeNotes
@ParameterizedTestMarks a test method as parameterizedRequired for parameterized tests
@MethodSource("methodName")Specifies the data provider methodMethod must be static and return Stream/Iterable/array
Static factory methodProvides test argumentsReturns Stream or similar
Arguments.of(...)Wraps parameters for each test caseUse 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.