Spring 3.2:@Scope("request") 的单元测试不再有效

Ale*_*sky 2 java spring unit-testing jax-rs

在 Spring 3.1 中,如果我包含以下 BeanFactoryPostProcessor,我可以将具有 `@Scope("request") 的 Jax-RS 资源自动装配到我的单元测试中:

@Component
public class MockRequestBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

public void postProcessBeanFactory(
        ConfigurableListableBeanFactory beanFactory) throws BeansException {

    beanFactory.registerScope("request", new RequestScope());
    MockHttpServletRequest request = new MockHttpServletRequest();
    ServletRequestAttributes attributes = new ServletRequestAttributes(request);
    RequestContextHolder.setRequestAttributes(attributes);
}
Run Code Online (Sandbox Code Playgroud)

}

在 Spring 3.2 中,第一个运行的测试方法有效,但所有后续的测试方法都得到

java.lang.IllegalStateException: No thread-bound request found: 您是指实际 Web 请求之外的请求属性,还是在原始接收线程之外处理请求?如果您实际上是在 Web 请求中操作并且仍然收到此消息,则您的代码可能在 DispatcherServlet/DispatcherPortlet 之外运行:在这种情况下,请使用 RequestContextListener 或 RequestContextFilter 来公开当前请求。

我怎样才能让我的测试重新工作?

M. *_*num 5

BeanFactoryPostProcessor是有缺陷的,它只运行一次,所以只有一个线程会有(不可重用)MockHttpServletRequest.

移动创建请求并将其存储在 中的代码RequestContextHolder应该移动到带@Before注释的方法中,并且在带@After注释的方法中,您应该清除RequestContextHolder.

@Before
public void init() {
    MockHttpServletRequest request = new MockHttpServletRequest();
    ServletRequestAttributes attributes = new ServletRequestAttributes(request);
    RequestContextHolder.setRequestAttributes(attributes);
}

@After
public void cleanUp() {
    RequestContextHolder.resetRequestAttributes();
}
Run Code Online (Sandbox Code Playgroud)

您仍然需要BeanFactoryPostProcessor来注册RequestScope.