Bird
Raised Fist0
JUnittesting~20 mins

@MethodSource for factory methods in JUnit - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
JUnit @MethodSource Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of @MethodSource supplying multiple arguments
Given the following JUnit 5 test code using @MethodSource, what will be the output when the test runs?
JUnit
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

public class CalculatorTest {

    static Stream<org.junit.jupiter.params.provider.Arguments> provideAddData() {
        return Stream.of(
            org.junit.jupiter.params.provider.Arguments.of(1, 2, 3),
            org.junit.jupiter.params.provider.Arguments.of(3, 4, 7),
            org.junit.jupiter.params.provider.Arguments.of(5, 5, 10)
        );
    }

    @ParameterizedTest
    @MethodSource("provideAddData")
    void testAdd(int a, int b, int expected) {
        assertEquals(expected, a + b);
    }
}
ATest fails because provideAddData returns Stream<Object> instead of Stream<Arguments>.
BAll 3 tests pass successfully.
CTest fails due to missing @Test annotation on provideAddData method.
DTest fails because testAdd method parameters do not match the Arguments count.
Attempts:
2 left
💡 Hint
Check the method signature and the parameter types in the test method.
❓ assertion
intermediate
1:30remaining
Correct assertion for @MethodSource test with multiple parameters
Which assertion correctly verifies the output of a method that adds two integers, when using @MethodSource to supply test data?
JUnit
static Stream<org.junit.jupiter.params.provider.Arguments> data() {
    return Stream.of(
        org.junit.jupiter.params.provider.Arguments.of(2, 3, 5),
        org.junit.jupiter.params.provider.Arguments.of(4, 5, 9)
    );
}

@ParameterizedTest
@MethodSource("data")
void testSum(int x, int y, int expected) {
    // Which assertion is correct here?
}
AassertFalse(x + y != expected);
BassertTrue(x + y == expected);
CassertEquals(x + y, expected);
DassertEquals(expected, x + y);
Attempts:
2 left
💡 Hint
Remember the order of parameters in assertEquals(expected, actual).
🔧 Debug
advanced
2:00remaining
Identify the cause of NoSuchMethodException in @MethodSource
A test using @MethodSource("testData") fails with NoSuchMethodException. What is the most likely cause?
JUnit
public class SampleTest {

    @ParameterizedTest
    @MethodSource("testData")
    void testExample(int input) {
        // test code
    }

    static Stream<Integer> testdata() {
        return Stream.of(1, 2, 3);
    }
}
AMethod name in @MethodSource is case-sensitive and does not match the actual method name.
BThe testdata method is not static.
CThe testdata method returns Stream<Integer> instead of Stream<Arguments>.
DThe testExample method has wrong parameter type.
Attempts:
2 left
💡 Hint
Check spelling and capitalization of the method name in @MethodSource.
❓ framework
advanced
2:00remaining
Behavior of @MethodSource with non-static factory method
What happens if a @MethodSource factory method is non-static in a JUnit 5 test class?
JUnit
public class DemoTest {

    @ParameterizedTest
    @MethodSource("dataProvider")
    void test(int val) {
        // test code
    }

    Stream<Integer> dataProvider() {
        return Stream.of(10, 20);
    }
}
ATest runs successfully because non-static factory methods are allowed by default.
BTest fails because the factory method returns Stream<Integer> instead of Stream<Arguments>.
CTest fails with an exception because @MethodSource factory methods must be static unless the test class is annotated with @TestInstance(Lifecycle.PER_CLASS).
DTest runs but only the first parameter value is used.
Attempts:
2 left
💡 Hint
Consider the lifecycle of the test class and how JUnit accesses factory methods.
🧠 Conceptual
expert
2:30remaining
Understanding parameter matching in @MethodSource with Arguments
Consider a @MethodSource factory method returning Stream with three parameters per Arguments. The test method has two parameters. What will happen when the test runs?
JUnit
static Stream<org.junit.jupiter.params.provider.Arguments> provideData() {
    return Stream.of(
        org.junit.jupiter.params.provider.Arguments.of(1, 2, 3),
        org.junit.jupiter.params.provider.Arguments.of(4, 5, 9)
    );
}

@ParameterizedTest
@MethodSource("provideData")
void testSum(int a, int b) {
    // test code
}
ATest fails with ParameterResolutionException due to parameter count mismatch.
BTest runs using only the first two parameters from Arguments, ignoring the third.
CTest runs but throws ArrayIndexOutOfBoundsException at runtime.
DTest runs successfully because extra parameters in Arguments are ignored.
Attempts:
2 left
💡 Hint
Check if the number of parameters in the test method matches the number of arguments supplied.

Practice

(1/5)
1. What is the main purpose of using @MethodSource in JUnit tests?
easy
A. To skip a test method during execution
B. To create a new test class automatically
C. To provide multiple sets of data to a single test method
D. To run tests in parallel threads

Solution

  1. Step 1: Understand the role of @MethodSource

    @MethodSource is used to supply multiple data sets to a single test method, allowing it to run multiple times with different inputs.
  2. Step 2: Compare options with this role

    Options B, C, and D describe unrelated features. Only To provide multiple sets of data to a single test method correctly describes the purpose of @MethodSource.
  3. Final Answer:

    To provide multiple sets of data to a single test method -> Option C
  4. Quick Check:

    @MethodSource = multiple data sets [OK]
Hint: Remember: @MethodSource feeds data to one test method [OK]
Common Mistakes:
  • Thinking @MethodSource creates tests automatically
  • Confusing @MethodSource with test skipping annotations
  • Assuming @MethodSource controls test threading
2. Which of the following is the correct way to declare a factory method for @MethodSource in JUnit 5?
easy
A. public static Stream<Arguments> provideData()
B. private Stream<Arguments> provideData()
C. public Stream<Arguments> provideData()
D. static Stream<Arguments> provideData()

Solution

  1. Step 1: Recall factory method requirements

    Factory methods used with @MethodSource must be static and public to be accessible by the test framework.
  2. Step 2: Check each option

    public static Stream<Arguments> provideData() is public and static, matching requirements. private Stream<Arguments> provideData() is private, so inaccessible. public Stream<Arguments> provideData() is public but not static. static Stream<Arguments> provideData() is static but missing public modifier.
  3. Final Answer:

    public static Stream<Arguments> provideData() -> Option A
  4. Quick Check:

    Factory method = public static [OK]
Hint: Factory methods must be public and static [OK]
Common Mistakes:
  • Omitting static keyword
  • Making the method private
  • Using wrong return type
3. Given the following code snippet, what will be the output when the test runs?
import static org.junit.jupiter.api.Assertions.assertEquals;
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 CalculatorTest {
    @ParameterizedTest
    @MethodSource("dataProvider")
    void testAdd(int a, int b, int expected) {
        assertEquals(expected, a + b);
    }

    static Stream<Arguments> dataProvider() {
        return Stream.of(
            Arguments.of(1, 2, 3),
            Arguments.of(2, 3, 5),
            Arguments.of(3, 5, 9)
        );
    }
}
medium
A. Test fails on the last data set because 3 + 5 != 9
B. All tests pass successfully
C. Compilation error due to missing imports
D. Runtime error because dataProvider is not static

Solution

  1. Step 1: Check each data set against the assertion

    First: 1 + 2 = 3 (matches expected 3), second: 2 + 3 = 5 (matches expected 5), third: 3 + 5 = 8 but expected is 9.
  2. Step 2: Identify test result

    The third test case fails because the expected value is incorrect.
  3. Final Answer:

    Test fails on the last data set because 3 + 5 != 9 -> Option A
  4. Quick Check:

    3+5=8 ≠ 9, test fails [OK]
Hint: Check each input-output pair carefully [OK]
Common Mistakes:
  • Assuming all tests pass without checking values
  • Ignoring the static keyword correctness
  • Confusing compilation and runtime errors
4. Identify the error in the following JUnit test using @MethodSource and suggest a fix:
import static org.junit.jupiter.api.Assertions.assertTrue;
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 SampleTest {
    @ParameterizedTest
    @MethodSource("numbers")
    void testIsPositive(int number) {
        assertTrue(number > 0);
    }

    Stream<Arguments> numbers() {
        return Stream.of(
            Arguments.of(1),
            Arguments.of(2),
            Arguments.of(3)
        );
    }
}
medium
A. The test method must return a value
B. The factory method 'numbers' must be static
C. The @MethodSource annotation should specify a class name
D. The Stream should contain Arguments objects, not Integers

Solution

  1. Step 1: Check factory method signature

    The method 'numbers' is not static, but factory methods for @MethodSource must be static to be accessible.
  2. Step 2: Suggest fix

    Make the 'numbers' method static by adding the static keyword.
  3. Final Answer:

    The factory method 'numbers' must be static -> Option B
  4. Quick Check:

    Factory method must be static [OK]
Hint: Factory methods must be static to be found [OK]
Common Mistakes:
  • Forgetting static keyword on factory method
  • Thinking test methods must return values
  • Assuming @MethodSource needs class name always
5. You want to test a method that calculates discounts for different customer types using @MethodSource. The factory method returns a Stream<Arguments> with customer type and expected discount. Which approach correctly handles a case where the discount is zero for unknown customer types without failing the test?
hard
A. Exclude unknown customer types from the factory method to avoid test failure
B. Use a separate test method without @MethodSource for unknown types
C. Throw an exception in the factory method for unknown customer types
D. Include an Arguments entry with unknown customer type and expected discount 0 in the factory method

Solution

  1. Step 1: Understand test coverage needs

    To test all cases including unknown customer types, the factory method should provide data for them explicitly.
  2. Step 2: Choose approach that includes zero discount case

    Including an Arguments entry with unknown type and expected discount 0 ensures the test runs and verifies correct behavior without failure.
  3. Final Answer:

    Include an Arguments entry with unknown customer type and expected discount 0 in the factory method -> Option D
  4. Quick Check:

    Test all cases by including zero discount data [OK]
Hint: Always include edge cases in factory data [OK]
Common Mistakes:
  • Skipping edge cases in factory method
  • Expecting exceptions instead of valid results
  • Splitting tests unnecessarily
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard