Java 使用Netty在Resteasy测试中注入上下文数据

Java 使用Netty在Resteasy测试中注入上下文数据,java,integration-testing,netty,resteasy,Java,Integration Testing,Netty,Resteasy,我正在尝试使用Resteasy测试一个资源,使用嵌入式Netty实例,如中所述 注入路径参数和查询参数就像一个符咒,但是我尝试测试一个从上下文注入HttpServletRequest和HttpServletResponse的资源,如下所示: @GET @Path("/") public void example(@Context HttpServletResponse response, @Context HttpServletRequest reque

我正在尝试使用Resteasy测试一个资源,使用嵌入式Netty实例,如中所述

注入路径参数和查询参数就像一个符咒,但是我尝试测试一个从上下文注入
HttpServletRequest
HttpServletResponse
的资源,如下所示:

@GET
@Path("/")
public void example(@Context HttpServletResponse response, 
                    @Context HttpServletRequest request) { ... }
Resteasy无法在上下文中找到
HttpServletRequest
,并引发以下异常:

5105 [r #1] DEB o.j.resteasy.core.SynchronousDispatcher  - PathInfo: /auth
5201 [r #1] ERR c.s.f.v.s.r.e.ApplicationExceptionMapper - Unhandled application exception: Unable to find contextual data of type: javax.servlet.http.HttpServletRequest
org.jboss.resteasy.spi.LoggableFailure: Unable to find contextual data of type: javax.servlet.http.HttpServletRequest
我尝试按照中的建议将请求和响应的模拟版本放在上下文中,但也不起作用,因为上下文数据是ThreadLocal,Netty会为每个请求生成一个新线程


关于如何解决这个问题有什么想法吗?

在我的案例中,有效的方法是注入org.jboss.seam.mock.HttpServletRequest,因为我在应用程序中使用了seam。您应该尝试一些模拟框架,如spring.test或mockito

下面是我的代码的样子:

import org.jboss.resteasy.core.Dispatcher;
import org.jboss.resteasy.mock.MockDispatcherFactory;
import org.jboss.resteasy.mock.MockHttpRequest;
import org.jboss.resteasy.mock.MockHttpResponse;
import org.jboss.resteasy.plugins.server.resourcefactory.POJOResourceFactory;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.jboss.seam.mock.MockHttpServletRequest;
import org.jboss.seam.mock.DBUnitSeamTest;

public class Test extends DBUnitSeamTest{   

    @Test
    public void test() throws Exception {

        Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();

        POJOResourceFactory noDefaults = new POJOResourceFactory(ClasstoBeTested.class);        dispatcher.getRegistry().addResourceFactory(noDefaults);
        MockHttpRequest request = MockHttpRequest.get("/serviceToBeTested/1961");
        MockHttpResponse response = new MockHttpResponse();

        HttpServletRequest servletRequest = new MockHttpServletRequest(getSession());
        ResteasyProviderFactory.getContextDataMap().put(HttpServletRequest.class, servletRequest);

        dispatcher.invoke(request, response);

        Assert.assertEquals(HttpServletResponse.SC_OK, response.getStatus());
        Assert.assertTrue(response.getContentAsString().contains("1961")); 

    }
}

我刚刚在另一个项目中再次受到这个问题的影响,并决定再次调查

问题在于,在使用Netty的模拟请求中,没有可用的
HttpServletRequest
。如果查看
NettyJaxrsServer
和相关类的源代码,Reasteasy会对未实现
HttpServletRequest
的http请求使用自己的抽象

如果我将实现更改为使用这些抽象,我可以访问资源中的请求和响应

import org.jboss.resteasy.spi.HttpRequest;
import org.jboss.resteasy.spi.HttpResponse;

@GET
@Path("/")
public void example(@Context HttpResponse response, 
                    @Context HttpRequest request) { ... }

这并不完美,因为它使我的资源依赖于Resteasy接口,但我决定现在就使用它来支持多部分数据的模拟测试。

有一个bug可以跟踪这一点,但它很旧:这适用于请求参数等简单场景,但使测试多部分上传等内容变得更加困难。我正在使用restasured来测试我的JAX-RS资源,我还必须模拟请求中的多部分。