[英]@parameters method is executed before @beforeclass method
我正在使用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;
}
}
现在,我正在@beforeclass方法中将变量“ initializeThis”初始化为true,但是(令人惊讶地)当我执行打印的测试用例时
Other test: First parameter :: adding false
Other test: Second parameter :: adding false
那是不期望的。
我的问题是; 有什么方法可以在@parameters之前执行@beforeclass方法,我们可以在junit 4中执行此操作吗?
我将只使用普通的老式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;
}
}
我知道的唯一缺点是,从此继承的类将无法覆盖静态初始化器,而@BeforeClass在这方面提供了一些自由;
这是个老问题,但最近我也遇到了同样的问题。 令我吃惊的是,所有解决方案似乎都不适合最明显的解决方法-在@Parameters方法中调用@BeforeClass方法。 后者是静态的,仅在执行任何测试之前执行一次。 因此,出于所有意图和目的,@ BeforeClass方法即使没有这样注释也是如此。 可以在这里找到更多详细信息: http : //feraldeveloper.blogspot.co.uk/2013/12/beforeclass-and-parametrized-junit-tests.html
JUnit为参数列表中的每个项目创建一个Runner
, Runner
封装了测试方法。 因此, @Parameters
将始终在@BeforeClass之前执行。
但是,您可以将@Parameterized与Assume结合使用。 无论您是否打算执行所有参数,都始终将其包含在列表中。 然后在测试方法中,添加用于对initializeThis
值进行测试的assumeTrue()
。
@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);
}
}
输出是:
Inside parameter
Doing setup before class...
Other test: Second
但是,这不适用于TestSuites。 给定
@RunWith(Parameterized.class)
public class TogglableParameterizedTest {
static boolean useAllParameters = false;
int parameter;
public TogglableParameterizedTest(int parameter) {
super();
this.parameter = parameter;
}
@Parameters
public static Collection<Object[]> getTestParameters() {
List<Object[]> parameters = new ArrayList<Object[]>();
if(useAllParameters) {
parameters.add(new Object[] { 1 });
parameters.add(new Object[] { 2 });
parameters.add(new Object[] { 3 });
}
else {
parameters.add(new Object[] { 1 });
}
return parameters;
}
@Test
public void test() {
System.out.println("parameter=" + parameter);
}
}
这不起作用:
@RunWith(Suite.class)
@SuiteClasses({ TogglableParameterizedTest.class })
public class NonWorkingTestSuite1 {
@BeforeClass
public static void toggle() {
System.out.println("sets flag to late!");
}
}
输出是
sets flag to late!
parameter=1
也没有:
@RunWith(Suite.class)
@SuiteClasses({ TogglableParameterizedTest.class })
public class NonWorkingTestSuite2 {
static {
System.out.println("sets flag still to late");
TogglableParameterizedTest.useAllParameters = true;
}
}
输出为“ parameter = 1”。 因此,静态初始化程序根本不会执行。 我发现以下解决方法。 扩展“ Suite”并在其中插入静态初始化程序:
public class TogglingSuite extends Suite {
static {
System.out.println("sets flag early enough!");
TogglableParameterizedTest.useAllParameters = true;
}
public TogglingSuite(Class<?> klass, Class<?>[] suiteClasses)
throws InitializationError {
super(klass, suiteClasses);
}
public TogglingSuite(Class<?> klass, List<Runner> runners)
throws InitializationError {
super(klass, runners);
}
public TogglingSuite(Class<?> klass, RunnerBuilder builder)
throws InitializationError {
super(klass, builder);
}
public TogglingSuite(RunnerBuilder builder, Class<?> klass,
Class<?>[] suiteClasses) throws InitializationError {
super(builder, klass, suiteClasses);
}
public TogglingSuite(RunnerBuilder builder, Class<?>[] classes)
throws InitializationError {
super(builder, classes);
}
}
并在测试套件中使用它:
@RunWith(TogglingSuite.class)
@SuiteClasses({ TogglableParameterizedTest.class })
public class WorkingTestSuite {
}
输出是
sets flag early enough!
parameter=1
parameter=2
parameter=3
现在可以了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.