【问题标题】:JUnit5 BeforeAllCallback is executed for every test class为每个测试类执行 JUnit5 BeforeAllCallback
【发布时间】:2021-06-16 23:29:57
【问题描述】:

我有以下课程:

public class MyExtension implements BeforeAllCallback, AfterAllCallback {
...
}

@SpringBootTest
@ExtendWith(MyExtension.class)
@ActiveProfiles("test")
class MyService1IT{
...
}

@SpringBootTest
@AutoConfigureMockMvc
@ExtendWith(MyExtension.class)
@ActiveProfiles("test")
class MyService2IT{
...
}

当使用 IntelliJ 的 Run All Testsmvn failsafe:integration-test 执行测试时,我可以清楚地看到每个类都在执行 beforeAllafterAll 方法。 我怎样才能避免这种情况?我虽然 ExtendWith 对于这些回调只会执行一次。

【问题讨论】:

    标签: java spring-boot junit


    【解决方案1】:

    不,ExtendWith 机制只允许您设计可重用的行为,但生命周期与@BeforeEach / @BeforeAll 方法非常相似。

    但没有什么能阻止您在扩展程序中实现自己的生命周期。 这里有一些代码可以确保它只被调用一次。

    private static final AtomicBoolean FIRST_TIME = new AtomicBoolean(true);
    
    // and in your method:
    
    if(FIRST_TIME.getAndSet(false)){
        // code here that should only be run once
    }
    

    请注意,此解决方案依赖于在同一个虚拟机/运行中。因此,如果每个测试或测试类都有 fork 模式,则需要使用一些外部同步方式。

    【讨论】:

    • junit.org/junit5/docs/5.5.2/api/org/junit/jupiter/api/extension/… 声明:“在调用所有测试之前测试容器的附加行为。”
    • 我同意措辞很糟糕。但我认为这里的重要部分是“测试容器”。如果我理解正确的话,一个类是一个测试容器,这将使语句正确。
    • 天哪。我很失望他们没有为此提供统一的方式。为每个集成测试类启动测试容器是不好的。然后我会继续自己保持状态并注册一个关闭钩子。谢谢
    • @Regyn 我自己没有尝试过,但看起来 ExtensionContext 可能是你想要的。 junit.org/junit5/docs/current/user-guide/…
    • 我喜欢它再次说“通常,扩展只实例化一次”。甚至构造函数也被多次调用。无论如何extensionContext.getRoot().getStore() 似乎确实有效,所以我可以将 + BeforeAllCallback 与 AtomicBool 一起使用。再次感谢您!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    • 2017-05-23
    • 2019-05-17
    • 2017-05-05
    • 1970-01-01
    • 2021-07-13
    • 2021-05-08
    相关资源
    最近更新 更多