当前位置: 首页 > 知识库问答 >
问题:

在单元测试期间注入模拟HttpServlet响应

刘令
2023-03-14

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

我们的服务是如何设置的示例(注意我没有控制/权限来更改非测试结构):

package services.example;

import org.springframework.http.MediaType;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;

@RestController
@Path("/base")
@Produces(MediaType.APPLICATION_JSON_VALUE);
public class ExampleService {

  @Autowired
  SomeInjectedService injectedService;

  @POST
  @Path("/endpoint")
  public Object testEndpoint(Object exampleInput, @Context HttpServletResponse response) {
    if (exampleInput.someMethod != null) {
      // Exception thrown here during tests, response is null!!!
      response.setStatus(301);
      return exampleInput;
    }

    return new injectedService.returnOutputFromInput(exampleInput);
  }
}

测试类:

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

}

我可能在这里做错了几件事,但是我希望我只需要在我的自定义调用器中加入正确的“魔法”,以便正确地向我的endpoint注入HttpServlet响应。我要注意的是,在我没有注入上下文的endpoint上,测试工作正常(当我删除我的自定义调用器位时)。

共有1个答案

袁翰池
2023-03-14

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

@InjectMocks
ExampleService service;

如果你想测试@Path(“/endpoint”),那么你做什么是对的,但很奇怪。如果要测试代码,只需执行以下操作:

  @Test
  public void testEndpointShouldReturn301() {
    service.testEndpoint(someObject, mockResponse);
    assertThat(response.getStatus(), is(301));
  }
 类似资料:
  • 我有以下用例: 问题2:为什么如果我只使用构造函数而不使用@Autowired或者反之亦然,那么一切都能正常工作,因为我没有加载Spring上下文...我有单元测试...

  • 问题内容: 这是我的java类: 这是单元测试: 测试失败,因为没有任何人注入。我应该如何正确处理这种情况?是否存在最佳实践? 问题答案: 如果没有像Spring这样的容器(或诸如基于Spring的Unitils之类的容器),则必须手动注入实体管理器。在这种情况下,您 可以 将以下内容用作基类:

  • 我的实现出了什么问题?谢谢

  • 问题内容: 每当我想测试使用资源注入的类时,我最终都会包含一个仅在测试中使用的构造函数: 还有另一种模拟资源注入的方式,或者这是遵循的正确模式吗? 问题答案: 您可以使用简单的光泽效果,它可以模拟EJB注入系统。 另一种方法是在测试中使用反射来设置字段,我有时使用类似这样的内容:

  • 我在尝试包装我的代码以用于单元测试时遇到了一些问题。问题是。我有接口IHttpHandler: 现在很明显,我将在Connection类中有一些方法,这些方法将从my后端检索数据(JSON)。但是,我想为这个类编写单元测试,显然我不想编写针对真实后端的测试,而是一个被嘲弄的测试。我曾尝试谷歌一个很好的答案,但没有很大的成功。我以前可以并且曾经使用过Moq来模拟,但是从来没有在像HttpClient

  • 问题内容: 我正在为启动a 并使用返回的诺言执行一些逻辑的控制器编写单元测试。我可以测试触发$ modal的父控制器,但是我一生无法弄清楚如何模拟成功的诺言。 我尝试了多种方法,包括使用和强制履行承诺。但是,我得到的最接近的结果是与本 SO帖子中的最后一个答案相似的东西。 我已经在“旧的” 模式中看到了几次这样的问题。在“新” 模式下,我找不到太多的方法。 一些指针将不胜感激。 为了说明问题,我使