@parameters方法在@beforeclass方法之前执行

use*_*r85 10 java junit junit4

我正在使用junit 4的"参数化"功能,我注意到@parameters方法在@beforeclass方法之前执行.这给我带来了一个问题,因为我通过@parameters传递给测试用例的参数取决于@beforeclass方法中初始化的代码.例如

@RunWith(Parameterized.class)
public class TestOtherClass {

    String argument;
    private static boolean initializeThis;

    public TestOtherClass(String parameter) throws Exception {
        argument=parameter;
    }

    @BeforeClass
    public static void doSetup() {
        System.out.println("Doing setup before class...");
        initializeThis=true; // true or false, based on some condition
    }

    @Test
    public void otherTest() {
        System.out.println("Other test: " + argument);
    }

    @Parameters
    public static Collection<Object[]> getData(){
        System.out.println("Inside parameter");
        String addThis;
        if(initializeThis)
            addThis="adding true";
        else
            addThis="adding false";

        Object[] para1 = new Object[]{"First parameter :: " + addThis};
        Object[] para2 = new Object[]{"Second parameter :: " + addThis};

        Collection<Object[]> classNames = new ArrayList<Object[]>();
        classNames.add(para1);
        classNames.add(para2);
        return classNames;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我在@beforeclass方法中将变量"initializeThis"初始化为true,但是(令人惊讶地)当我执行测试用例时它会打印出来

Other test: First parameter :: adding false
Other test: Second parameter :: adding false
Run Code Online (Sandbox Code Playgroud)

这是不期望的.
我的问题是; 有没有办法在@parameters之前执行@beforeclass方法,我们可以在junit 4中执行此操作吗?

小智 6

我会使用普通的旧java静态{..}初始化程序而不是@BeforeClass,例如:

@RunWith(Parameterized.class)
public class TestOtherClass {

    String argument;
    private static boolean initializeThis;

    public TestOtherClass(String parameter) throws Exception {
        argument=parameter;
    }

    static {
        doSetup();
    }

    // @BeforeClass
    public static void doSetup() {
        System.out.println("Doing setup before class...");
        initializeThis=true; // true or false, based on some condition
    }

    @Test
    public void otherTest() {
        System.out.println("Other test: " + argument);
    }

    @Parameters
    public static Collection<Object[]> getData(){
        System.out.println("Inside parameter");
        String addThis;
        if(initializeThis)
            addThis="adding true";
        else
            addThis="adding false";

        Object[] para1 = new Object[]{"First parameter :: " + addThis};
        Object[] para2 = new Object[]{"Second parameter :: " + addThis};

        Collection<Object[]> classNames = new ArrayList<Object[]>();
        classNames.add(para1);
        classNames.add(para2);
        return classNames;
    }
}
Run Code Online (Sandbox Code Playgroud)

我所知道的唯一缺点就是从这个继承的类将无法覆盖静态初始化器,而@BeforeClass在这方面提供了一些自由;


Mat*_*ell 1

RunnerJUnit为参数列表中的每一项创建一个a ,aRunner是封装测试方法的东西。所以@Parameters总是会在@BeforeClass之前执行。

但是,您可以将 @Parameterized 与Assume结合起来。无论您是否打算执行它,您始终将所有参数包含在列表中。然后在测试方法中,添加assumeTrue()针对该initializeThis值进行测试。

@RunWith(Parameterized.class)
public class TestOtherClassAssume {
  private final String argument;
  private final boolean initializeThisTest;
  private static boolean initializeThis;

  @Parameters
  public static Collection<Object[]> getData(){
    System.out.println("Inside parameter");

    return Arrays.asList(new Object[][] {
      { false, "First" },
      { true, "Second" },
    });
  }

  public TestOtherClassAssume(boolean initializeThisTest, String argument) {
    this.initializeThisTest = initializeThisTest;
    this.argument = argument;
  }

  @BeforeClass
  public static void doSetup() {
    System.out.println("Doing setup before class...");
    initializeThis = true; // true or false, based on some condition
  }

  @Test
  public void otherTest() {
    Assume.assumeTrue(initializeThis == initializeThisTest);
    System.out.println("Other test: " + argument);
  }
}
Run Code Online (Sandbox Code Playgroud)

其输出是:

Inside parameter
Doing setup before class...
Other test: Second
Run Code Online (Sandbox Code Playgroud)