Spring测试@ContextConfiguration和静态上下文

Vic*_*Vic 3 junit spring

我有我的抽象测试类(我知道下面的代码段XmlBeanFactoryClassPathResource已过时,但它不可能是问题的情况下).

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public abstract class AbstractIntegrationTest {

    /** Spring context. */
    protected static final BeanFactory context = new XmlBeanFactory(new ClassPathResource(
            "com/.../AbstractIntegrationTest-context.xml"));

    ...

}
Run Code Online (Sandbox Code Playgroud)

它加载默认的测试配置XML文件AbstractIntegrationTest-context.xml(然后我使用自动装配).我还需要在使用@BeforeClass和注释的静态方法中使用Spring @AfterClass,因此我有一个指向同一位置的单独上下文变量.但事实是,这是一个单独的上下文,它将具有不同的bean实例.那么如何合并这些上下文或如何调用@ContextConfiguration我的静态上下文定义的Spring的bean初始化?

我想通过摆脱那些静态成员可能的解决方案,但我很好奇,如果我可以通过相对较小的代码更改来做到这一点.

Tom*_*icz 8

您是对的,您的代码将生成两个应用程序上下文:一个将通过@ContextConfiguration注释为您启动,缓存和维护.您自己创建的第二个上下文.两者都没有多大意义.

不幸的是,JUnit不太适合集成测试 - 主要是因为你不能拥有课前课后的非静态方法.我看到两个选择:

  • 切换到 - 我知道这是一个很大的进步

  • 仅在测试期间在上下文中包含的Spring bean中编码您的setup /拆除逻辑 - 但是在所有测试之前它只运行一次.

也有不太优雅的方法.您可以使用static变量和注入上下文:

private static ApplicationContext context;

@AfterClass
public static afterClass() {
    //here context is accessible
}

@Autowired
public void setApplicationContext(ApplicationContext applicationContext) {
    context = applicationContext;
}
Run Code Online (Sandbox Code Playgroud)

或者你可以@DirtiesContext在一些测试bean中注释你的测试类并进行清理:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@DirtiesContext(classMode = AFTER_CLASS)
public abstract class AbstractIntegrationTest {

    //...

}

public class OnlyForTestsBean {

    @PreDestroy
    public void willBeCalledAfterEachTestClassDuringShutdown() {
        //..
    }

}
Run Code Online (Sandbox Code Playgroud)


Sen*_*Zhe 6

不确定你是否在这里选择了任何方法,但我遇到了同样的问题并使用Spring测试框架以另一种方式解决了它TestExecutionListener.

beforeTestClassafterTestClass,所以两者都相当于@BeforeClass@AfterClassJUnit.

我这样做的方式:

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners(Cleanup.class)
@ContextConfiguration(locations = { "/integrationtest/rest_test_app_ctx.xml" })
public abstract class AbstractIntegrationTest {
    // Start server for integration test.
}
Run Code Online (Sandbox Code Playgroud)

您需要创建一个扩展AbstractTestExecutionListener的类:

public class Cleanup extends AbstractTestExecutionListener
{

   @Override
   public void afterTestClass(TestContext testContext) throws Exception
   {
      System.out.println("cleaning up now");
      DomainService domainService=(DomainService)testContext.getApplicationContext().getBean("domainService");
      domainService.delete();

   }
}
Run Code Online (Sandbox Code Playgroud)

通过这样做,您可以访问应用程序上下文并使用spring bean进行设置/拆卸.

希望这有助于任何人尝试像我一样使用JUnit + Spring进行集成测试.