Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring 3.2:@Scope(“请求”)的单元测试不再有效_Java_Spring_Unit Testing_Jax Rs - Fatal编程技术网

Java Spring 3.2:@Scope(“请求”)的单元测试不再有效

Java Spring 3.2:@Scope(“请求”)的单元测试不再有效,java,spring,unit-testing,jax-rs,Java,Spring,Unit Testing,Jax Rs,在Spring 3.1中,如果我包含以下BeanFactoryPostProcessor,我可以将具有`@Scope(“request”)的Jax RS资源自动连接到我的单元测试中: @Component public class MockRequestBeanFactoryPostProcessor implements BeanFactoryPostProcessor { public void postProcessBeanFactory( ConfigurableLis

在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);
}
}

在Spring3.2中,运行的第一个测试方法是有效的,但是所有后续的测试方法都是有效的

java.lang.IllegalStateException:未找到线程绑定请求:您是指实际web请求之外的请求属性,还是在原始接收线程之外处理请求?如果您实际上在web请求中操作,并且仍然收到此消息,那么您的代码可能在DispatcherServlet/DispatcherPortlet之外运行:在这种情况下,请使用RequestContextListener或RequestContextFilter公开当前请求


如何使测试重新工作?

BeanFactoryPostProcessor有缺陷,它只运行一次,因此只有一个线程具有(不可重用的)
MockHttpServletRequest

移动创建请求并将其存储在
RequestContextHolder
中的代码时,应将其移动到
注释方法,而在
@After
注释方法中,应清除
RequestContextHolder

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

@After
public void cleanUp() {
    RequestContextHolder.resetRequestAttributes();
}

您仍然需要
BeanFactoryPostProcessor
来注册
RequestScope

Spring3.2引入了
ServletTestExecutionListener
,它粗暴地将自己注入到旧的测试中

其javadoc:

TestExecutionListener,它为SpringTestContext框架加载的WebApplicationContext提供模拟Servlet API支持

具体来说,ServletTestExecutionListener在测试实例准备期间和每个测试方法之前通过SpringWeb的RequestContextHolder设置线程本地状态,并基于WebApplicationContext中的MockServletContext创建MockHttpServletRequest、MockHttpServletResponse和ServletWebRequest。此侦听器还确保可以将MockHttpServletResponse和ServletWebRequest注入测试实例,测试完成后,此侦听器将清除线程本地状态

请注意,默认情况下已启用ServletTestExecutionListener,但如果为当前测试加载的ApplicationContext不是WebApplicationContext,则不会采取任何操作

问题是最后一段是谎言。诚然,除非您进行配置更改,否则该类不会开始帮助您,但无论发生什么情况,它都会在每次测试后愉快地重置请求

可以通过向测试类添加
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class})
来禁用侦听器。(您可能需要根据需要编辑的实际侦听器集。)


或者,您可以设置
@WebAppConfiguration
并删除MockRequestBeanFactoryPostProcessor以及其他遗留解决方案,如MockServletContextawareReprocessor。

这不起作用,因为在调用方法之前,Spring会在@之前自动连接我的测试类。您可以改为执行查找。您可以添加/尝试的另一件事是将
@WebAppConfiguration
注释添加到您的测试类中(我假设您正在使用Springs测试支持来加载和自动连接)。这将消除对
BeanFactoryPostProcessor
@Before
/
@After
方法的需要。请添加您的测试类。我将使用默认值并放弃解决方法(需要维护的代码更少:))。很好地捕捉到了重置,您可能需要为此注册一个bug/enhanchement。@M.Deinum事情是,根据,我对ServletContext和单元测试做了一些有趣的事情。我需要设置资源路径,但是
@WebAppConfiguration.value
在编译时得到修复。因此,我想我会继续使用我的自定义ServletContextaware。在任何情况下,当我手动运行junit(通过JUnitCore编程)时,内置的SCAP都无法工作(
@WAC
bug?),因此我别无选择。但是我似乎可以同时使用
@WAC
和我的自定义SCAP,同时跳过
RequestBeanFactoryPostProcessor