junitjunit-runner

how to combine @RunWith with @RunWith(Parameterized.class)


I implemented a runner class A.class inherited from BlockJUnit4ClassRunner so that I can annotate tests with @RunWith(A.class). At the same time, sb. else annotate the tests with RunWith(Parameterized.class). It is obvious we cannot use two @RunWith at the same time.

How to solve this problem? or how to merge these two @RunWith?


Solution

  • I believe this does what you want:

    package so.junit.runner;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.junit.runners.Parameterized;
    import org.junit.runners.model.InitializationError;
    import org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParameters;
    import org.junit.runners.parameterized.ParametersRunnerFactory;
    import org.junit.runners.parameterized.TestWithParameters;
    
    import java.util.Arrays;
    
    @RunWith(Parameterized.class)
    @Parameterized.UseParametersRunnerFactory(CustomParameterizedTest.RunnerFactory.class)
    public class CustomParameterizedTest {
    
      @Parameterized.Parameters
      public static Iterable<Integer> data() {
        return Arrays.asList(new Integer[]{1, 2, 3});
      }
    
      private int i;
    
      public CustomParameterizedTest(int i) {
        this.i = i;
      }
    
      @Test
      public void test() {
        System.out.println(i);
      }
    
      public static class RunnerFactory implements ParametersRunnerFactory {
        @Override
        public org.junit.runner.Runner createRunnerForTestWithParameters(TestWithParameters test) throws InitializationError {
          return new A(test);
        }
      }
    
      public static class A extends BlockJUnit4ClassRunnerWithParameters {
        private final Object[] parameters;
    
        public A(TestWithParameters test) throws InitializationError {
          super(test);
          parameters = test.getParameters().toArray(new Object[test.getParameters().size()]);
        }
    
        @Override
        public Object createTest() throws Exception {
          return getTestClass().getOnlyConstructor().newInstance(parameters);
        }
      }
    }
    

    Based on the Javadocs in the JUnit Parameterized class, this is how they expect you to create a custom test runner that supports parameterization.

    UPDATE

    Updated to name the custom runner A