Java 在单元测试期间注入模拟HttpServletResponse

Java 在单元测试期间注入模拟HttpServletResponse,java,jax-rs,mockito,cxf,junit4,Java,Jax Rs,Mockito,Cxf,Junit4,问题一:在对CXF JAX-RS服务端点进行单元测试期间,如何注入模拟(或真实?)HttpServletResponse 我们的服务设置示例(注意,我无权更改非测试结构): 测试等级: package test.services.example // A gazillion imports. Mockito, JUnit, Hamcrest, Javax.ws.rs, org.apache.cxf, Jackson providers. public class testExampleSe

问题一:在对CXF JAX-RS服务端点进行单元测试期间,如何注入模拟(或真实?)HttpServletResponse

我们的服务设置示例(注意,我无权更改非测试结构):

测试等级:

package test.services.example

// A gazillion imports.  Mockito, JUnit, Hamcrest, Javax.ws.rs, org.apache.cxf, Jackson providers.

public class testExampleService {

  @Mock
  private HttpServletResponse mockResponse; // Should I do this?

  @Mock
  SomeInjectedService mockInjectionService;

  @InjectMocks
  ExampleService service = new ExampleService();

  @Before
  public void setUpStuff() {
    MockitoAnnotations.initMocks(this);

    JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
    sf.setResourceClasses(ExampleService.class);

    List<Object> providers = new ArrayList<Object>;
    JacksonJsonProvider provider = new JacksonJsonProvider();
    providers.add(provider);

    sf.setProviders(providers);

    sf.setResourceProvider(ExampleService.class, new SingletonResourceProvider(service, true));
    sf.setAddress("local://someuri");

    // This is where I'm trying to set up my injected Response context.  Help?
    sf.setInvoker(new Invoker() {
      Invoker jarsInvoker = new JAXRSInvoker();

      @Override
      public Object invoke(Exchange exchange, Object o) {
        // What goes in here?  I've seen an example for setting a mock
        // Request context, but no for a Response.  Here's my current 
        // (broken) attempt to do this...
        exchange.getInMessage().put(AbstractHTTPDestination.HTTP_RESPONSE, mockResponse);
        return jarsInvoker.invoke(exchange, o);
      }
    });
  }

  @Test
  public void testEndpointShouldReturn301() {
    List<Object> providers = new ArrayList<Object>();
    JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider();
    providers.add(provider);

    WebClient client = WebClient.create("local://someuri", providers);
    WebClient.getConfig(client)
             .getRequestContext()
             .put(LocalConduit.DIRECT_DISPATCH, Boolean.TRUE);

    // Exception thrown here, Response context doesn't get injected!
    client.path("/base/endpoint");
    SomeTestObject obj = new SomeTestObject();
    Response response = client.type(MediaType.APPLICATION_JSON).post(obj);

    // Never gets run because an exception was thrown :(
    assertThat(response.getStatus(), is(301));
  }

}
package test.services.example
//大量进口。Mockito、JUnit、Hamcrest、Javax.ws.rs、org.apache.cxf、Jackson提供商。
公共类testExampleService{
@嘲弄
私有HttpServletResponse mockResponse;//我应该这样做吗?
@嘲弄
SomeInjectedService模拟InjectionService;
@注射模拟
ExampleService=新的ExampleService();
@以前
公共物品{
initMocks(this);
JAXRSServerFactoryBean sf=新的JAXRSServerFactoryBean();
sf.setResourceClasses(ExampleService.class);
列表提供程序=新的ArrayList;
JacksonJsonProvider provider=新的JacksonJsonProvider();
提供者。添加(提供者);
sf.setProviders(提供者);
setResourceProvider(ExampleService.class,新的SingletonResourceProvider(service,true));
sf.setAddress(“local://someuri");
//这就是我尝试设置注入响应上下文的地方。帮助?
setInvoker(新的Invoker(){
调用程序jarsInvoker=new JAXRSInvoker();
@凌驾
公共对象调用(Exchange,对象o){
//这里有什么?我看过一个设置模拟的例子
//请求上下文,但没有响应。这是我当前的
//(断开)尝试这样做。。。
exchange.getInMessage().put(AbstractHTTPDestination.HTTP_响应,mockResponse);
返回jarsInvoker.invoke(exchange,o);
}
});
}
@试验
public void testEndpointShouldReturn301(){
列表提供程序=新的ArrayList();
JacksonJaxbJsonProvider=新的JacksonJaxbJsonProvider();
提供者。添加(提供者);
WebClient客户端=WebClient.create(“local://someuri“,供应商);
WebClient.getConfig(客户端)
.getRequestContext()
.put(localconductor.DIRECT\u分派,布尔值.TRUE);
//此处引发异常,未注入响应上下文!
client.path(“/base/endpoint”);
SomeTestObject obj=新的SomeTestObject();
响应=client.type(MediaType.APPLICATION_JSON).post(obj);
//从不运行,因为引发了异常:(
断言(response.getStatus(),是(301));
}
}

我可能在这里做了一些错误的事情,但我希望我只需要在自定义调用程序中加入正确的“魔力”,以便正确地将HttpServletResponse注入到我的端点。我要注意,在没有注入上下文的端点上,测试可以正常工作(当我删除自定义调用程序位时).

您不必使用构造函数初始化示例服务,只需保留以下内容:

@InjectMocks
ExampleService service;
如果您想测试@Path(“/endpoint”),那么您所做的是正确的,但很奇怪。 如果要测试代码,请执行以下操作:

  @Test
  public void testEndpointShouldReturn301() {
    service.testEndpoint(someObject, mockResponse);
    assertThat(response.getStatus(), is(301));
  }

感谢您的回答,但测试的目的是确保对给定端点的REST调用命中预期的回调函数。在测试过程中,重要的是要检查(在我的示例中)发送到“/endpoint”的邮件是否始终触发testEndpoint()方法。
  @Test
  public void testEndpointShouldReturn301() {
    service.testEndpoint(someObject, mockResponse);
    assertThat(response.getStatus(), is(301));
  }