1

在单元测试中有很多关于请求范围管理的问题,主要的答案是不要测试范围管理,因为它是一个 Spring Framework 任务,应该注意它是否正常工作。例如,建议将请求范围替换为 XML 配置文件中的线程或原型类型范围。

对于大多数测试来说已经足够了,没有关于未注册“请求”范围的抱怨,并且测试运行良好。但我确实有一个案例是不够的。

考虑以下情况:

@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,那么在两个测试中,我将收到相同的MyServiceand实例MyComponent,因此例如test2()可能会收到错误的结果,MyComponent因为它可能在内部包含之前的一些内部“垃圾”test1()

变体 B

如果我用原型范围替换请求范围 - 我会遇到我的测试方法正在接收不同实例的MyComponent情况MyService- 所以我不能对它们执行任何断言。

所以我需要的是一种与测试方法相关的请求范围,其中所有请求范围的 bean 仅在test1()方法期间保留,然后被销毁,因此接下来test2()将再次创建它们。

可能吗?

4

2 回答 2

0

这可能不是您想要的,但您为什么首先使用 Spring 来管理您的测试类?这对我来说似乎有点矫枉过正。对于单元测试,您不需要 DI 容器。只需模拟依赖项并专注于您正在测试的组件或服务的封装功能。

但是,在使用字段注入时,您将无法做到这一点。您需要转换为构造函数或方法注入。

于 2012-04-17T16:20:04.237 回答
0

通过使用@DirtiesContext. 这允许您在应用程序上下文中为一个单元测试操作 bean,而不会影响其他单元测试。

文档

您的示例注释为@DirtiesContext

@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
    @DirtiesContext
    public void test1() {
        service.doSomething("aaa");

        assertEquals("AAA", component.getTheThing());
    }

    @Test
    @DirtiesContext
    public void test2() {
        service.doSomething("bbb");

        assertEquals("BBB", component.getTheThing());
    }

}

如果你的类中的所有测试方法都需要一个新的上下文,你也可以只注释类,如下所示:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:my-scope-tweaks.xml"})
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
public class MyServiceTest {
   //Tests Here...
}
于 2013-11-08T16:54:32.770 回答