我正在使用Spring 4 Test上下文框架对statefull spring服务进行一些集成测试。以下是将问题提炼为最基本形式的代码。
@Service
public class StatefullService {
private List<String> items = new Vector<>();
public void add(String item){
items.add(item);
}
public List<String> currentState()
{
return new ArrayList<>(items);
}
}
@ContextConfiguration(locations = { "classpath:spring.xml" })
public class Test1 extends AbstractTestNGSpringContextTests {
@Autowired
private StatefullService service;
@Test
public void addA()
{
service.add("A");
Assert.assertTrue(service.currentState().contains("A"));
}
}
Spring Test Context框架将缓存Spring Context,以便后续测试用例不需要重建spring上下文。
@ContextConfiguration(locations = { "classpath:spring.xml" })
public class Test2 extends AbstractTestNGSpringContextTests {
@Autowired
private StatefullService service;
@Test
public void addD()
{
Assert.assertTrue(service.currentState().isEmpty()); // assertion fails here
service.add("D");
Assert.assertTrue(service.currentState().contains("D"));
}
}
当Test2
运行addD()
时,方法会失败,因为StatefullService
已经有&#34; A&#34;在列表中。将@DirtiesContext
添加到Test1
将导致spring知道Test1
将弄脏上下文,因此后续测试应该重新初始化。
@DirtiesContext
说当前的测试会污染上下文,是否有注释说明上下文是脏的?
像@RefreshCachedContext
这样的东西会迫使spring刷新缓存的上下文,无论我在寻找什么。
答案 0 :(得分:1)
如果您不想在实际上污染上下文的测试中使用@DirtiesContext
,而是想强制Spring重新加载当前测试中使用的上下文,则可以添加一个虚拟配置文件(这样可以工作,因为上下文缓存基于配置的位置和使用的配置文件。)
我会不自己在代码中使用此解决方案,因为它肯定会有一种hacky感觉,但它可以用于你想要做的事情。
@ContextConfiguration(locations = { "classpath:spring.xml" })
@ActiveProfiles("dummyProfileNotUsedElsewhere")
public class Test2 extends AbstractTestNGSpringContextTests {
@Autowired
private StatefullService service;
@Test
public void addD()
{
Assert.assertTrue(service.currentState().isEmpty()); // assertion fails here
service.add("D");
Assert.assertTrue(service.currentState().contains("D"));
}
}
你不想要使用这样的东西的另一个原因是,如果你开始养成使用它的习惯,你的测试执行速度将会大大降低