我有一种情况需要能够在2种不同的“模式”下运行一套JUnit测试:
@Before
和@After
注释/方法;但是... @Test
方法例如:
public class WidgetTest {
@Before
void start() {
// Do some start up work.
}
@After
void stop() {
// Do some shutdown work.
}
@Test
public void testWidget() {
// Given/When/Then, etc.
}
}
在“模式#1”中,我希望@Before
和@After
方法(分别为start()
和stop()
)在testWidget()
之前/之后执行。但在“模式#2”中,我只希望触发testWidget()
方法。
我能想到的最好的是:
public class WidgetTest {
private boolean useHooks;
// Ctor, getter and setter for 'useHooks'.
@Before
void start() {
if(useHooks) {
// Do some start up work.
}
}
@After
void stop() {
if(useHooks) {
// Do some shutdown work.
}
}
@Test
public void testWidget() {
// Given/When/Then, etc.
}
}
但是这会带来一个额外的问题:如何将useHooks
注入我的测试套件?它也有点hacky,我想我希望JUnit支持这个开箱即用的用例。
有没有办法实现这个目标?如果是这样,怎么样?
答案 0 :(得分:1)
查看@Category
注释
答案 1 :(得分:1)
我建议考虑这个解决方案:
以下是我提出的自定义选手的代码:
import java.util.Collections;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.internal.runners.statements.RunAfters;
import org.junit.internal.runners.statements.RunBefores;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;
public class MyJUnitRunner extends BlockJUnit4ClassRunner {
private final boolean runBeforesAndAfters = System.getProperty("run-befores-and-afters") != null;
public MyJUnitRunner(Class<?> klass) throws InitializationError {
super(klass);
}
@Override
protected Statement withBefores(FrameworkMethod method, Object target, Statement statement) {
List<FrameworkMethod> befores = Collections.EMPTY_LIST;
if (runBeforesAndAfters) {
befores = getTestClass().getAnnotatedMethods(Before.class);
}
return befores.isEmpty() ? statement : new RunBefores(statement, befores, target);
}
@Override
protected Statement withAfters(FrameworkMethod method, Object target, Statement statement) {
List<FrameworkMethod> afters = Collections.EMPTY_LIST;
if (runBeforesAndAfters) {
afters = getTestClass().getAnnotatedMethods(After.class);
}
return afters.isEmpty() ? statement : new RunAfters(statement, afters, target);
}
}
只需添加此选项即可启动JUnits VM:-Drun-befores-and-afters
并使用@RunWith(MyJUnitRunner.class)
注释您的测试类,然后就完成了。
答案 2 :(得分:1)
您要找的是Parameterized tests,因此您的代码将如下所示(未经过测试)
@RunWith(Parameterized.class)
public class WidgetTest {
@Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[] {true, false});
}
private boolean useHooks
public WidgetTest(booelan useHooks) {
this.useHooks = useHooks;
}
....
}