Java 使用前后挂钩运行JUnit测试
我需要能够在两种不同的“模式”下运行一套JUnit测试:Java 使用前后挂钩运行JUnit测试,java,junit,Java,Junit,我需要能够在两种不同的“模式”下运行一套JUnit测试: 在第一种模式下,在使用注释/方法之前使用@和之后使用@;但是 在第二种模式下,不要使用这些注释/方法,而是运行相同的@Test方法 例如: public class WidgetTest { @Before void start() { // Do some start up work. } @After void stop() { // Do some shu
- 在第一种模式下,在使用注释/方法之前使用
和之后使用@
@;但是
- 在第二种模式下,不要使用这些注释/方法,而是运行相同的
方法@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”中,我希望在testWidget()之前/之后执行
和
方法(start()
和stop()
)。但是在“模式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
注入到测试套件中?它也是一种黑客行为,我想我希望JUnit支持这种开箱即用的用例
有没有办法做到这一点?如果是这样,如何?< P>检查<代码> @类别< /代码>注释< /P> < P>我建议考虑这个解决方案:
- 编写自定义JUnit runner
- 添加VM参数以在两种所需模式之间切换
以下是我找到的自定义跑步者的代码:
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);
}
}
import java.util.Collections;
导入java.util.List;
导入org.junit.After;
导入org.junit.Before;
导入org.junit.internal.runners.statements.runafter;
导入org.junit.internal.runners.statements.RunBefores;
导入org.junit.runners.BlockJUnit4ClassRunner;
导入org.junit.runners.model.FrameworkMethod;
导入org.junit.runners.model.InitializationError;
导入org.junit.runners.model.Statement;
公共类MyJUnitRunner扩展了BlockJUnit4ClassRunner{
私有最终布尔值runbeforesandafter=System.getProperty(“runbefores and after”)!=null;
公共MyJUnitRunner(类klass)引发初始化错误{
超级(klass);;
}
@凌驾
带befores的受保护语句(FrameworkMethod方法、对象目标、语句){
List befores=Collections.EMPTY_List;
if(运行前和运行后){
befores=getTestClass().getAnnotatedMethods(Before.class);
}
return befores.isEmpty()?语句:new RunBefores(语句,befores,目标);
}
@凌驾
带after的受保护语句(FrameworkMethod方法、对象目标、语句){
List after=Collections.EMPTY_List;
if(运行前和运行后){
After=getTestClass().getAnnotatedMethods(After.class);
}
return after.isEmpty()?语句:新建runafter(语句、after、目标);
}
}
你所要做的就是启动JUnits虚拟机,并添加以下选项:-Drun before and after
,用@RunWith(MyJUnitRunner.class)
注释你的测试类,然后你就完成了。你想要的是,所以你的代码看起来像这样(未测试)
@RunWith(参数化的.class)
公共类Widgetest{
@参数
公共静态收集数据(){
返回Arrays.asList(新对象[]{true,false});
}
私有布尔钩子
公共Widgetest(booelan useHooks){
this.useHooks=useHooks;
}
....
}
谢谢@robocoder(+1)-这是一个不错的建议,但这意味着我需要在两个地方定义我的testWidget()
方法(一个在使用这些启动/停止方法的测试类中,另一个在不使用它们的测试类中)。对我来说,这是太多的重复代码了,因为每个测试类都有几十个测试方法,而我有数百个测试类。思想?再次感谢!
@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;
}
....
}