3

我的抽象测试类有以下代码(我知道XmlBeanFactorywithClassPathResource已被弃用,但不太可能出现问题)。

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

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

    ...

}

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

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

4

2 回答 2

8

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

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

  • 切换到 - 我知道这是一大步

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

还有一些不太优雅的方法。您可以使用static变量并向其注入上下文:

private static ApplicationContext context;

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

@Autowired
public void setApplicationContext(ApplicationContext applicationContext) {
    context = applicationContext;
}

或者您可以使用一些测试 bean 注释您的测试类@DirtiesContext并进行清理:

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

    //...

}

public class OnlyForTestsBean {

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

}
于 2012-08-29T16:38:57.063 回答
6

不确定您是否在这里选择了任何方法,但我遇到了同样的问题并使用 Spring 测试框架的TestExecutionListener.

beforeTestClassand ,所以在 JUnit 中afterTestClass都等价于@BeforeClassand 。@AfterClass

我这样做的方式:

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

您需要创建一个扩展 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();

   }
}

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

希望这可以帮助任何尝试像我一样使用 JUnit + Spring 进行集成测试的人。

于 2013-11-06T07:20:55.040 回答