Ram*_*esh 73 junit spring spring-test junit4
我们有一堆JUnit测试用例(集成测试),它们在逻辑上分为不同的测试类.
我们能够为每个测试类加载一次Spring应用程序上下文,并将其重用于JUnit测试类中的所有测试用例,如http://static.springsource.org/spring/docs/current/spring-framework-reference中所述./html/testing.html
但是,我们只是想知道是否有一种方法只为一堆JUnit测试类加载一次Spring应用程序上下文.
FWIW,我们使用Spring 3.0.5,JUnit 4.5并使用Maven来构建项目.
Tom*_*icz 86
是的,这是完全可能的.您所要做的就是locations
在测试类中使用相同的属性:
@ContextConfiguration(locations = "classpath:test-context.xml")
Run Code Online (Sandbox Code Playgroud)
Spring按locations
属性缓存应用程序上下文,因此如果locations
第二次出现相同的情况,Spring会使用相同的上下文而不是创建新的上下文.
我写了一篇关于此功能的文章:加速Spring集成测试.另外,它在Spring文档中有详细描述:9.3.2.1上下文管理和缓存.
这有一个有趣的含义.因为Spring不知道JUnit什么时候完成,所以它会永远缓存所有上下文并使用JVM shutdown hook关闭它们.这种行为(特别是当你有很多不同的测试类时locations
)可能导致过多的内存使用,内存泄漏等.缓存上下文的另一个好处.
ger*_*tan 25
要添加到Tomasz Nurkiewicz的答案,从Spring 3.2.2开始,@ContextHierarchy
注释可用于具有单独的,相关联的多个上下文结构.当多个测试类想要共享(例如)内存数据库设置(数据源,EntityManagerFactory,tx管理器等)时,这很有用.
例如:
@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 {
...
}
Run Code Online (Sandbox Code Playgroud)
通过此设置,使用"test-db-setup-context.xml"的上下文将只创建一次,但其中的bean可以注入到单个单元测试的上下文中
更多的手册:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/testing.html#testcontext-ctx-management(搜索" 上下文结构 ")
值得注意的一点是,如果我们再次使用 @SpringBootTests use @MockBean in different test classes
,Spring 就无法为所有测试重用其应用程序上下文。
解决方案是to move all @MockBean into an common abstract class
解决问题。
@SpringBootTests(webEnvironment = WebEnvironment.RANDOM_PORT, classes = Application.class)
public abstract class AbstractIT {
@MockBean
private ProductService productService;
@MockBean
private InvoiceService invoiceService;
}
Run Code Online (Sandbox Code Playgroud)
然后测试类如下所示
public class ProductControllerIT extends AbstractIT {
// please don't use @MockBean here
@Test
public void searchProduct_ShouldSuccess() {
}
}
public class InvoiceControllerIT extends AbstractIT {
// please don't use @MockBean here
@Test
public void searchInvoice_ShouldSuccess() {
}
}
Run Code Online (Sandbox Code Playgroud)
基本上,如果您在不同的测试类中具有相同的应用程序上下文配置,那么 spring 足够智能,可以为您配置此功能。例如,假设您有两个类 A 和 B,如下所示:
@ActiveProfiles("h2")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class A {
@MockBean
private C c;
//Autowired fields, test cases etc...
}
@ActiveProfiles("h2")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class B {
@MockBean
private D d;
//Autowired fields, test cases etc...
}
Run Code Online (Sandbox Code Playgroud)
在此示例中,类 A 模拟 bean C,而类 B 模拟 bean D。因此,spring 将它们视为两种不同的配置,因此将为类 A 加载应用程序上下文一次,为类 B 加载一次应用程序上下文。
相反,如果我们想让 spring 在这两个类之间共享应用程序上下文,它们必须如下所示:
@ActiveProfiles("h2")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class A {
@MockBean
private C c;
@MockBean
private D d;
//Autowired fields, test cases etc...
}
@ActiveProfiles("h2")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class B {
@MockBean
private C c;
@MockBean
private D d;
//Autowired fields, test cases etc...
}
Run Code Online (Sandbox Code Playgroud)
如果你像这样连接你的类,spring只会为类A或B加载一次应用程序上下文,具体取决于测试套件中首先运行的两个类中的哪个类。这可以在多个测试类中复制,唯一的标准是您不应该以不同的方式自定义测试类。任何导致测试类与其他类不同(在 spring 看来)的定制最终都会由 spring 创建另一个应用程序上下文。
归档时间: |
|
查看次数: |
61579 次 |
最近记录: |