英文:
How to execute some code using context before/after all tests with SpringExtension?
问题
我需要在使用 DI 容器时,在所有测试(所有类中的所有测试)之前/之后执行一些初始化/反初始化代码,当使用 SpringExtension
时。我尝试了两种解决方案:
@ExtendWith({BeforeAllAfterAll.class, SpringExtension.class})
@ContextConfiguration(classes = ContextConfig.class)
public class ServiceIT { ... }
public class BeforeAllAfterAll implements BeforeAllCallback,
ExtensionContext.Store.CloseableResource { ... }
然而,在 BeforeAllAfterAll
类中,我无法获取应用程序上下文的引用。
我尝试使用事件:
public class ContextEventHandler {
@EventListener
public void handleContextStartedEvent(ContextStartedEvent event) {
System.out.println("接收到上下文启动事件。");
}
@EventListener
public void handleContextRefreshEvent(ContextRefreshedEvent event) {
System.out.println("接收到上下文刷新事件。");
}
@EventListener
public void handleContextStoppedEvent(ContextStoppedEvent event) {
System.out.println("接收到上下文停止事件。");
}
}
然而,我发现当使用 SpringExtension
时,StartedEvent
和 StoppedEvent
并不会被触发。
有人可以说明如何做吗?我使用 Spring5 和 JUnit5。
英文:
I need to execute some initialization / deinitialization code before/after all tests (in all classes) using DI container when SpringExtension
is used. I tried two solutions:
@ExtendWith({BeforeAllAfterAll.class, SpringExtension.class})
@ContextConfiguration(classes = ContextConfig.class)
public class ServiceIT{..}
public class BeforeAllAfterAll implements BeforeAllCallback,
ExtensionContext.Store.CloseableResource {...}
However, in BeforeAllAfterAll
class I can't get reference to application context.
I tried to use events:
public class ContextEventHandler {
@EventListener
public void handleContextStartedEvent(ContextStartedEvent event) {
System.out.println("Context Start Event received.");
}
@EventListener
public void handleContextRefreshEvent(ContextRefreshedEvent event) {
System.out.println("Context Refreshed Event received.");
}
@EventListener
public void handleContextStoppedEvent(ContextStoppedEvent event) {
System.out.println("Context Stopped Event received.");
}
}
However, as I found out when SpringExtension
is used StartedEvent
and StoppedEvent
are not fired.
Could anyone say how to do it? I use Spring5 and JUnit5.
答案1
得分: 0
在研究了 spring-test 源代码后,我采用了以下解决方案:
public class BeforeAllAfterAll implements BeforeAllCallback, ExtensionContext.Store.CloseableResource {
private static boolean started = false;
private TestEnvironment testEnvironment;
@Override
public void beforeAll(ExtensionContext context) {
if (!started) {
started = true;
// 在这里编写你的“所有测试之前”启动逻辑
Namespace springNamespace = Namespace.create(SpringExtension.class);
Store store = context.getRoot().getStore(springNamespace);
// 需要传递任何测试类
TestContextManager testContextManager =
store.getOrComputeIfAbsent(FooTest.class, TestContextManager::new, TestContextManager.class);
ApplicationContext applicationContext = testContextManager.getTestContext().getApplicationContext();
testEnvironment = applicationContext.getBean(TestEnvironment.class);
testEnvironment.initialize();
// 下面一行代码在根测试上下文关闭时注册回调钩子
context.getRoot().getStore(GLOBAL).put("任何唯一名称", this);
}
}
@Override
public void close() {
testEnvironment.deinitialize();
}
}
也许有人可以提供更好的建议。
英文:
After studying spring-test source code I did the following solution:
public class BeforeAllAfterAll implements BeforeAllCallback, ExtensionContext.Store.CloseableResource {
private static boolean started = false;
private TestEnvironment testEnvironment;
@Override
public void beforeAll(ExtensionContext context) {
if (!started) {
started = true;
// Your "before all tests" startup logic goes here
Namespace springNamespace = Namespace.create(SpringExtension.class);
Store store = context.getRoot().getStore(springNamespace);
//we need to pass any test class
TestContextManager testContextManager =
store.getOrComputeIfAbsent(FooTest.class, TestContextManager::new, TestContextManager.class);
ApplicationContext applicationContext = testContextManager.getTestContext().getApplicationContext();
testEnvironment = applicationContext.getBean(TestEnvironment.class);
testEnvironment.initialize();
// The following line registers a callback hook when the root test context is shut down
context.getRoot().getStore(GLOBAL).put("any unique name", this);
}
}
@Override
public void close() {
testEnvironment.deinitialize();
}
}
Maybe someone can suggest something better.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论