我打算在这里介绍一些有关缓存的注意事项,这可能并不全面,但是基于我遇到的某些情况:
1.缓存基于Spring应用程序上下文文件的位置
考虑一个示例Spring配置文件:
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<beans xmlns='http://www.springframework.org/schema/beans'xmlns:context='http://www.springframework.org/schema/context'xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'xmlns:p='http://www.springframework.org/schema/p'xsi:schemaLocation='http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd'><bean id='user1' class='org.bk.lmt.domain.TaskUser' p:username='user1' p:fullname='testUser1' /><bean name='user2' class='org.bk.lmt.domain.TaskUser' p:username='user2' p:fullname='testUser' /><bean class='org.bk.contextcaching.DelayBean'/></beans>
还有一个样本测试,用于加载此上下文文件并进行验证。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { 'contexttest.xml' })
public class Test1 {@Autowired Map<String, TaskUser> usersMap;@Testpublic void testGetAUser() {TaskUser user = usersMap.get('user1');assertThat(user.getFullname(), is('testUser1'));}
}
我故意添加了一个bean(DelayBean),它花了大约2秒钟来实例化,以模拟加载缓慢的Spring Application Context。
如果我现在运行一个带有两个测试的小型测试套件,两个测试都使用相同的应用程序上下文,则行为是第一个测试需要大约2秒钟才能运行,但是第二个测试由于上下文缓存而很快就可以运行。
如果使用不同的应用程序上下文进行了第三项测试,则该测试将再次花费时间来运行,因为必须加载新的应用程序上下文:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { 'contexttest2.xml' })
public class Test3 {
...
}
2.应用程序上下文的缓存尊重运行测试的活动配置文件–本质上,该配置文件也是Spring用于缓存上下文的内部密钥的一部分,因此,如果两个测试使用的是完全相同的应用程序上下文,但不同的配置文件是对于每个测试都处于活动状态,则缓存的应用程序上下文将不会用于第二个测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { 'contexttest.xml' })
@ActiveProfiles('dev1')
public class Test1 {
....
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { 'contexttest.xml' })
@ActiveProfiles('dev2')
public class Test2 {
....
3.即使使用新的@Configuration样式定义应用程序上下文并在测试中使用它,应用程序上下文的缓存也适用:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={TestConfiguration.class})
public class Test1 {
...
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={TestConfiguration.class})
public class Test2 {
....
缓存的一个含义是,如果测试类修改了bean的状态,则测试套件中使用缓存的应用程序上下文的另一个类将最终看到修改后的bean,而不是在应用程序上下文中定义的bean。 :
例如。 考虑两个测试,这两个测试都在上下文中修改了一个bean,但是在状态中声明了它在应用程序上下文中定义的方式–在这里,其中一个测试最终会失败(基于Junit执行测试的顺序) ):
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={TestConfiguration.class})
public class Test1 {@Autowired Map<String, TaskUser> usersMap;@Testpublic void testGetAUser1() {TaskUser user = usersMap.get('user1');assertThat(user.getFullname(), is('testUser1'));user.setFullname('New Name');}@Testpublic void testGetAUser2() {TaskUser user = usersMap.get('user1');assertThat(user.getFullname(), is('testUser1'));user.setFullname('New Name');}
}
解决方法是指示Spring测试支持人员该应用程序上下文现在很脏并且需要为其他测试重新加载,这是通过@DirtiesContext批注完成的,可以在测试类级别或测试方法级别指定该批注。
@Test
@DirtiesContext
public void testGetAUser2() {
...
祝您编程愉快,别忘了分享!
参考: all和其他博客中的JCG合作伙伴 Biju Kunjummen提供的Spring测试支持和上下文缓存 。
翻译自: https://www.javacodegeeks.com/2012/09/spring-testing-support-and-context.html