Spring Test - 每个项目的JavaConfig

时间:2014-09-21 17:52:09

标签: java spring unit-testing spring-java-config

我的系统中有各种单元测试类,它们都扩展了一个名为AbstractContextTest的集中测试类。所述抽象超类通常如下所示:

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class})
@ContextConfiguration(locations = {"/TestContext.xml"})
public class AbstractContextTest {
  // Various utility methods that would be useful in a unit test.
  ...
}

这里要注意的重要事项是@ContextConfiguration行。它使用locations属性加载存储在XML文件中的测试应用程序上下文。它通过使用相对路径来工作,这允许我执行以下操作:

  1. 我将AbstractContextTest超类放在自己的项目中。
  2. 我将其他项目配置为将AbstractContextTest项目作为测试级依赖项。
  3. 我在每个项目中都放置了一个名字相同的TestContext.xml'测试资源。
  4. 当我运行所有单元测试时,由于相对路径,每个项目都使用其本地TestContext.xml
  5. 一切都是对的。
  6. 现在对于实际问题:我希望从Spring XML Application Contexts的宁静时代进入Spring JavaConfigs的勇敢新世界。在这个范例中,是否有相当于我的相对路径解决方案?如果是这样,我该怎么把它拉下来?

3 个答案:

答案 0 :(得分:0)

您可以在每个项目的@Configuration中放置具有相同名称的src/test/java类,并获得相同的效果。但是,在这一点上,你可能过于聪明,我建议为每个项目都有一个单独的中间抽象基础测试类。

答案 1 :(得分:0)

@ContextConfiguration具有classes属性,允许您指定Java配置文件而不是XML上下文。但是,由于我们正在处理类,您需要使用Java配置添加类,因此必须将其添加到导入中。因此,您无法在测试项目中声明@ContextConfiguration(classes = TestConfig.class),因为如果没有具体的类,它将无法编译(以后您将在下游项目中创建不同的实现,这对AbstractContextTest项目没有帮助编译)。这是一件好事,因为这意味着你必须在测试中明确你的Java配置。毕竟,有一个原因,你首先创建了单独的项目。

就个人而言,我更喜欢在相关测试中使用Spring特定注释的两个额外行。第一行清楚地表明它是基于Spring的测试(与一般的jUnit测试相反),第二行告诉我在哪里找到相关的应用程序上下文:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestConfig.class)
public class DownStreamProjectTest extends AbstractContextTest {

    // tests
}

旁注,我建议不要将DirtiesContextTestExecutionListener放在通用测试类层次结构中。它将导致Spring为每个测试重新创建整个应用程序上下文,这将显着增加测试套件的周转时间。

答案 2 :(得分:0)

对于任何一直好奇的人,我会继续前进并展示我最终的正确解决方案。我很确定这是chrylis所描述的内容,但他却拒绝展示它的例子或以任何方式解释它。

所以这里是abstract超类本身:

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners(DependencyInjectionTestExecutionListener.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
public abstract class AbstractContextTest {
  @Configuration
  @ComponentScan(basePackages = "my.package.name.test",
                 includeFilters = @Filter(type = FilterType.ANNOTATION,
                                          value = Configuration.class))
  static class ContextConfiguration {}
}

然后在src/test/java下的其他项目中,在与abstract超类中的扫描包匹配的包中(在这种情况下," my.package.name.test") ,你有一个上下文类,你可以命名你喜欢的任何名称。我选择了" TestContext"对于这个例子:

package my.package.name.test;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = "package.under.test")
public class TestContext {}