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

时间:2016-05-31 14:46:59

标签: spring spring-test

我们有一个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上下文中运行,并从它访问它在另一个上下文中运行的静态字段开始。

有没有人能解决这个问题?有没有人陷入同样的​​境地?

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题。 可能的解决方案可能是在测试之前保存上下文并在之后恢复它。 为方便起见,可以通过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();