javajunit4junit5parameterized-tests

ParametrizedTest with displayName and Argument


I am trying to migrate from JUnit4 to JUnit5 and also I'm new to ParametrizedTest in Junit5 and I have a scenario wherein I would like to provide different DisplayName and the Test argument(Object).

Here's the data source I would like to use as an input for @MethodSource("data")

    public static Collection<Object[]> data() throws IOException {
    List<Object[]> testCaseData = new ArrayList<>();
    TestCaseReader testCaseReader = new TestCaseReader(TESTCASE_CSV_RESOURCE);
    List<MyClass> testCaseList = testCaseReader.readTestCases();

    for (MyClass testCase : testCaseList) {
        if (testCase.isActive()) {
            Object[] testParameter = new Object[2];
            testParameter[0] = String.format("%03d: %s", testCase.getStartingLineNumber(), testCase.getName());
            testParameter[1] = testCase;
            testCaseData.add(testParameter);
        }
    }
    return testCaseData;
}

And this is the Test

@ParameterizedTest(name = "Scenario: {0}, testCase={1}")
@MethodSource("data")
public void process(MyClass testCase) {
//...
 //some operating on testCase methods/variables
}

When executing TestCase, I see the DisplayName is picked up correctly, but the other arguments is not resolvable it says

org.junit.jupiter.api.extension.ParameterResolutionException: Failed to resolve parameter [com.sample.MyClass testCase] in method [public void.MultipleTestCase.process(com.sample.MyClass testCase)]

Could you please guide me what I have done wrong here!

Thanks


Solution

  • Providing test data as Collection<Object[]> is no longer the appropriate way in JUnit 5. You can use a Stream instead. If you need to provide multiple parameters for your test you can use Arguments to wrap them. They are automatically unwrapped upon test execution. The example below gives a general idea on how to do that. You can replace TestCase with MyClass and insert your TestCaseReader code in data.

    public class ParameterizedTest {
    
      static Stream<Arguments> data() {
        // TODO: Add your TestCaseReader usage to create MyClass / TestCase instances.
        List<TestCase> testCases =
            List.of(new TestCase("test01", "data01"), new TestCase("test02", "data02"));
    
        return testCases.stream().map(test -> Arguments.arguments(test.getName(), test));
      }
    
      @org.junit.jupiter.params.ParameterizedTest(name = "Scenario: {0}, testCase={1}")
      @MethodSource("data")
      public void process(String name, TestCase testCase) {
        System.out.println(name + ": " + testCase.getData());
        // TODO: Work with your test case.
      }
    
      private static final class TestCase {
        private final String name;
        private final String data;
    
        public TestCase(String name, String data) {
          this.name = name;
          this.data = data;
        }
    
        public String getName() {
          return name;
        }
    
        public String getData() {
          return data;
        }
      }
    }