与纯@ContextConfiguration相比,使用@ContextHierarchy有什么好处

时间:2017-04-29 11:00:27

标签: spring junit applicationcontext context-configuration

嗨,我不明白有什么好处可以让我使用@ContextHierarchy,如下所示:

@ContextHierarchy({
  @ContextConfiguration("/test-db-setup-context.xml"),
  @ContextConfiguration("FirstTest-context.xml")
})
@RunWith(SpringJUnit4ClassRunner.class)
public class FirstTest {
 ...
}

@ContextHierarchy({
  @ContextConfiguration("/test-db-setup-context.xml"),
  @ContextConfiguration("SecondTest-context.xml")
})
@RunWith(SpringJUnit4ClassRunner.class)
public class SecondTest {
 ...
}

过度使用带有locations参数的单个@ContextConfiguration,如下所示:

@ContextConfiguration(locations = {"classpath:test-db-setup-context.xml", "FirstTest-context.xml", "SecondTest-context.xml" })

在每种情况下,应用程序上下文都在不同的junit测试类中共享。

2 个答案:

答案 0 :(得分:2)

不同之处在于,上下文层次结构中每个上下文中的bean都无法在另一个上下文中看到bean。因此,您可以隔离测试项目的不同部分。

答案 1 :(得分:0)

在这里需要注意的一个不可思议的事情是,在@ContextHierarchy的情况下,我们会得到具有 SEPARATE 生命周期(初始化,关闭)的 SEPARATE 上下文。这很重要,因为例如它们可以独立失败。

我院子里的一个实际例子。我们有一个Spring应用程序,可以与某些外部服务进行通信。我们想要一个E2E测试,以启动这些依赖服务并运行测试。因此,我们在@ContextConfiguration中添加了一个初始化程序:

@ContextConfiguration{classes = TheApp.class, initializers = DockerInitializer.class}
public class TheAppE2ETests {
    // ...
}

初始化程序正在准备外部服务(启动Docker),自定义属性,以便App可以运行并附加到close上下文事件,以便可以清理Docker。当App上下文无法加载时(例如由于错误),这种方法存在问题:

  1. 初始化失败后,ContextClosedEvent不会被触发-码头工人并未停止并清理。
  2. 当上下文无法加载时,将为运行的每个测试(不仅是每个测试类-每个测试方法!)反复调用初始化程序。

因此,每当The App上下文中的错误导致初始化失败时,测试就不断杀死我们的CI环境。每种测试方法都会启动用于依赖服务的容器,然后不对其进行清理。

我们最终使用了@ContextConfiguration,并为docker和The App本身提供了两个单独的上下文。通过这种方式,在上述情况下,泊坞窗是在单独的上下文中启动的,因此可以自己生活,甚至可以在多个Spring测试中共享(由于Spring的上下文缓存机制)。