Spring静态上下文访问器和集成测试



我们有一个spring组件,它将应用程序上下文设置为一个静态字段。然后从应用程序的其他部分访问该静态字段。我知道不应该使用static,但有时有必要从非spring托管bean访问spring上下文。例如,字段如下所示:

public class ApplicationContextProvider implements ApplicationContextAware {
private static ApplicationContext context;
public ApplicationContext getApplicationContext() {
return context;
}
@Override
public void setApplicationContext(ApplicationContext ctx) {
context = ctx;
}
}

(被视为http://www.dcalabresi.com/blog/java/spring-context-static-class/)

问题是,当在集成测试中使用JUnit(或Spock)框架时,会为具有@TestPropertySource@ContextConfiguration等注释的测试创建一个新的spring上下文,在这种情况下,会为其他具有相同配置的测试缓存上下文(spring测试框架中的上下文缓存)。

但是,只有在创建弹簧上下文时才会更新静态字段。这意味着,当从缓存中检索测试上下文时,它当然不会更新静态字段,因为上下文在缓存之前已经初始化。静态字段已经被以前使用不同配置运行的测试创建的最后一个上下文覆盖,因此它看不到与启动测试的上下文相同的上下文。

结果是,部分测试在一个spring上下文中运行,从访问静态字段开始,它在另一个上下文中运行。

有人能解决这个问题吗?有人遇到同样的情况吗?

我也遇到过同样的问题。可能的解决方案可能是在测试前保存上下文,然后再进行恢复。为了方便起见,可以通过junit规则进行:

public class ContextRestoreRule extends ExternalResource {
private ApplicationContext context;
@Override
protected void before() throws Throwable {
context = ApplicationContextProvider.getContext();
}
@Override
protected void after() {
ApplicationContextProvider.setContext(context);
}
}

在测试中(修改上下文):

@ClassRule
public static ContextRestoreRule contextRestore = new ContextRestoreRule();

最新更新