我们通过测试规则为每个测试强制执行超时:
public abstract class BaseTestCase {
@Rule
public final Timeout timeout = new Timeout(60*1000);
}
然后我们的 GUI 测试显然必须在 EDT 上运行,因此他们也有一个测试规则:
public class TestSomeController extends BaseTestCase {
@Rule
public final RunOnEventDispatchThread runOnEventDispatchThread =
new RunOnEventDispatchThread();
@Test
public void testStuff() { /* ... */ }
}
这两条规则都涉及扰乱测试运行的线程。 Timeout
创建一个新线程,然后在 N 毫秒后将其终止。 RunOnEventDispatchThread
在 EDT 上运行一个 Runnable
,然后等待任务完成。
直到 JUnit 4.10,这一直工作正常,但我们刚刚升级到 JUnit 4.11,现在测试规则的顺序似乎已经改变。
当前的 JUnit 似乎以“逻辑”顺序应用规则,因此它应用 Timeout
,然后应用 RunOnEventDispatchThread
。
这意味着 RunOnEventDispatchThread
在 Statement
“onion”的“外部”结束。所以它在 EDT 上运行任务,但该任务现在是“产生一个新线程来运行测试”——因为它产生了一个新线程,测试失败了,因为现在在错误的线程上调用了 Swing 调用。
显然,JUnit 4.10 正在以另一种顺序运行测试规则。有办法影响这一点吗?
请注意,此类问题的现有答案均已使用 RuleChain
解决。据我所知,我们不能使用 RuleChain
,因为该类要求两个规则都在同一个类中,而我们的则不需要。
最佳答案
我不是很熟悉 JUnit 中的规则排序,尤其是 RuleChain
类。所以我快速浏览了一下这个类' documentation .在模板方法意义上使用时,示例代码片段似乎是您的解决方案。
我可以想象以下机制会起作用:
public abstract class BaseTestCase {
@Rule
public final RuleChain ruleChain = createRuleChain();
private RuleChain createRuleChain() {
return appendInnerRules(RuleChain.outerRule(createOuterRule()));
}
protected TestRule createOuterRule() {
return new Timeout(60 * 1000);
}
protected RuleChain appendInnerRules(RuleChain ruleChain) {
return ruleChain; // default behavior
}
}
public final class TestSomeController extends BaseTestCase {
protected RuleChain appendInnerRules(RuleChain ruleChain) {
return ruleChain.around(new RunOnEventDispatchThread());
}
@Test
public void testStuff() { /* ... */ }
}
关于java - 如何按特定顺序应用我的 JUnit 规则?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23624186/