单元测试中有很多关于请求作用域管理的问题,主要答案是不测试作用域管理,因为它是Spring框架的一项任务,应该注意它的正常工作。所以建议,例如,将XML请求范围替换为XML配置文件中的线程或原型类型范围。单元测试中的请求作用域Bean管理
对于大多数测试来说,没有关于未注册“请求”范围和测试运行良好的投诉。但我确实有一个案例不足。
考虑以下情况:
@Component
@Scope("request")
public class MyService {
@Autowired
private MyComponent component;
public void doSomething(String param) {
component.doTheThing(param);
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:my-scope-tweaks.xml"})
public class MyServiceTest {
@Autowired
private MyService service;
@Autowired
private MyComponent component;
@Test
public void test1() {
service.doSomething("aaa");
assertEquals("AAA", component.getTheThing());
}
@Test
public void test1() {
service.doSomething("bbb");
assertEquals("BBB", component.getTheThing());
}
}
我想测试的MyService,这是在请求范围内。 MyComponent
也是请求范围。
方案A
如果我更换SimpleThreadScope
请求范围,然后由这两个测试中,我会接受的MyService
和MyComponent
同一个实例,因此,例如test2()
可以从MyComponent
得到不好的结果,因为它可以在内部包含从一些内部的“垃圾”以前test1()
方案B
如果我有原型范围替换请求范围 - 我会得到我的地方测试方法receivin的情况下g MyComponent
的不同实例与MyService
不同 - 因此我无法对它们执行任何断言。
所以我需要的是一种与测试方法相关的请求范围,其中所有请求范围的bean只保留在test1()
方法中,然后被销毁,所以在下一个test2()
中,它们将再次被新创建。
可能吗?
目前我正在进行的一种集成测试。对于小的单元测试,我不使用DI,但在这种情况下 - 它的更大和更多的注入出现(示例被简化,以更好地解释) - 所以它是矫枉过正的重做所有工作手动春天通常做的... – Laimoncijus 2012-04-17 16:40:20
I看看你现在在说什么。但是,如何注入'Component'仍然存在代码异味。您希望Spring为每次测试重新注入它,但即使在原型范围(变体B)中也不会发生。 Spring只会注入一次对象。要做你想做的事情,你必须为每个需要的对象实际拥有一个'Context'和_ask_ Spring的副本。另外,你是否可以通过'MyService'对象访问需要声明的状态,而不是需要单独的'Component'副本? – 2012-04-17 20:17:05
你是对的,通过'MyService'通过原型访问'MyComponent'会为我做这件事,所以我不需要另外在我的测试类中使用'@ Autowire'。 – Laimoncijus 2012-04-18 12:01:21