简体   繁体   中英

JUnit: inject @Parameterized parameters?

What's the easiest way of injecting a set of parameters to a @Parameterized test class?

Use case:

I have a regular class that looks like this

@RunWith(Parameterized.class)
class Tests {

    public void testOne() { }
    public void testTwo() { }

    @Parameters
    public static Collection<Object[]> generateData() { }

}

A standard JUnit runner can be invoked like this: org.junit.runner.JUnitCore.runClasses(TestClass1.class, ...);

however, there is no way of then specifying/overriding the parameters.

How can I inject my own parameters?

junit is not designed for running someone else's junit class with your parameters. so if possible, refactor you test classes to make them support your desired behavior. if you can't refactor then all you can do is to use some workarounds. for example:

  • if test class is written 'correctly' (eg no static references) then you can inherit from the test class and provide your own parameters. but still you have to provide parameters explicitly in class file, not during run
  • you can try to use custom class loader and bytecode generation/transformation to change the parameter provider method on class load. same way as PowerMockito works
  • write you custom runner so it will ignore in-class parameters and use your own instead

I would use a generateData() method which generates all five hundred elements. In addition, I would add a method getParameters() annotated with @Parameters . It could invoke generateData() to get the full collection, then load the log file (if present) and reduce the collection to the failing test parameters. If no log file is present, it will return the whole collection. You might need to explicitly name your parameters to be able to identify them because JUnit is not guaranteed to re-run the tests / test parameters in the same order (see Changing names of parameterized tests ).

@RunWith(Parameterized.class)
public class Tests {

  @Parameters
  public static Collection<Object[]> getParameters() {
    List<Object[]> parameters = generateData();
    return filterParameters(parameters);
  }

  private static Collection<Object[]> filterParameters(Collection<Object[]> params) {
    // load a file to exclude successful tests
    // ...
  }

  private static Collection<Object[]> generateData() {
    return new ArrayList<Object[]>();
  }
}

Another way might be to use a Scanner with System.in in the @Parameters method so that you can select the parameters with user input from the console. However, you will need to ensure somehow that the tests can still be run without user interaction if you want to use them in continuous integration.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM