【发布时间】:2012-10-22 18:05:33
【问题描述】:
我的测试类中的所有测试在执行每个测试之前都会执行一个“之前”方法(使用 JUnit 的 @Before 注释)。
我需要一个特定的测试来不执行这个之前的方法。
有办法吗?
【问题讨论】:
我的测试类中的所有测试在执行每个测试之前都会执行一个“之前”方法(使用 JUnit 的 @Before 注释)。
我需要一个特定的测试来不执行这个之前的方法。
有办法吗?
【问题讨论】:
您可以使用TestRule 来完成此操作。你用一些描述的注释标记你想要跳过的测试,然后,在 TestRule 的 apply 方法中,你可以测试那个注释并做你想做的事情,比如:
public Statement apply(final Statement base, final Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
if (description.getAnnotation(DontRunBefore.class) == null) {
// run the before method here
}
base.evaluate();
}
};
}
【讨论】:
// run the before method here 部分的最简单方法是什么。
考虑使用@Enclosed 运行器以允许您拥有两个内部测试类。一个带有所需的@Before 方法,另一个没有。
@RunWith(Enclosed.class)
public class Outer{
public static class Inner1{
@Before public void setup(){}
@Test public void test1(){}
}
public static class Inner2{
// include or not the setup
@Before public void setup2(){}
@Test public void test2(){}
}
}
【讨论】:
不幸的是,您必须编写此逻辑。 JUnit 没有这样的特性。 通常你有两种解决方案:
@RequiresBefore 并使用此注解标记需要此注解的测试。测试运行器将解析注解并决定是否运行“之前”方法。第二种解决方案更清晰。第一个比较简单。这取决于您选择其中之一。
【讨论】:
这个问题早就有人问过了,不过还是想分享一下我的解决方法:
用@Tag("skipBeforeEach")注释想要的方法
在你的 setup() 方法中:
@BeforeEach
void setup(final TestInfo info) {
final Set<String> testTags = info.getTags();
if(testTags.stream()
.filter(tag->tag.equals("skipBeforeEach"))
.findFirst()
.isPresent()){
return;
}
// do your stuff
}```
【讨论】:
也可以通过撤消测试用例中@Before setup 中所做的操作来解决此问题。
看起来是这样的,
@Before
public void setup() {
TestDataSetupClass.setupTestData();
}
@Test
public void testServiceWithIgnoreCommonSetup() {
TestDataSetupClass.unSet();
//Perform Test
}
这里的解决方案有利有弊。次要缺点是设置和取消设置步骤的不必要循环。但是,如果只需要为数百个测试用例中的一个测试用例,并且避免编写自己的 AOP 或维护多个内部测试类的开销,那就很好了。
【讨论】:
我正在寻找解决此问题的方法并遇到了这个问题。作为更新,在 JUnit 5 中,现在可以使用 @Nested annotation 轻松完成此操作。
【讨论】:
如果您使用的是 Mockito,尤其是 Mockito 3.0,则所有存根都将是“严格的”并默认经过验证。
您可以使用 Mockito lenient() 方法。
更多:https://www.baeldung.com/mockito-unnecessary-stubbing-exception#lenient-stubbing
【讨论】:
如果你有一个@After 方法可以清除@Before 中所做的工作,你可以在@Test 方法的开头手动调用@After 方法。
【讨论】: