【问题标题】:How to mock test REST client?如何模拟测试 REST 客户端?
【发布时间】:2012-10-23 13:45:38
【问题描述】:

我有一个正在尝试测试的 Rest 服务客户端。 这是我要测试的客户端方法:

public RestPriceRow getPriceRow(String customer, String product, String qt)
    throws Exception {
    // Prepare acceptable media type
    List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>();
    acceptableMediaTypes.add(MediaType.APPLICATION_XML);

    // Prepare header
    HttpHeaders headers = new HttpHeaders();
    headers.setAccept(acceptableMediaTypes);
    HttpEntity<PriceRowDto> entity = new HttpEntity<PriceRowDto>(headers);

    // Prepare response
    RestPriceRow res = new RestPriceRow();

    // Send the request as GET
    try {
        ResponseEntity<PriceRowDto> result =
          restTemplate.exchange(baseURL + "{customerId}/{productId}/{quantity}",
          HttpMethod.GET, entity, PriceRowDto.class, customer,product,qt);
        PriceRowDto response = result.getBody();
        return response;
    } catch (Exception e) {
        e.printStackTrace();
    }
}

这是我的测试课:

@Before
public void setUp() {
    RestTemplate r = mock(RestTemplate.class);
    restPriceService = new RestPriceServiceImpl();
    restPriceService.setRestTemplate(r);
    restPriceService.setBaseURL("url");
}

@Test
public void prueba() {
    PriceRowDto r = new PriceRowDto("100","200","9","10","0","19/11/2012");
    try {
        when(restPriceService.getPriceRow("100","200","16")).thenReturn(r);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

我的问题是,当我运行这个测试时,它在执行result.getBody() 时会抛出一个NullPointerException。 (结果为空)

【问题讨论】:

  • 你不测试 getPriceRow,你模拟它。你测试什么?你的 SUT(被测系统)是什么,被嘲笑的合作者是什么?
  • 我以为我没有嘲笑服务.. 那么我需要更改什么来测试 getPriceRow?

标签: unit-testing rest mocking mockito


【解决方案1】:

您将 SUT(被测系统)与模拟的协作者混为一谈。 SUT 是您测试的方法。协作者根据 SUT 工作的需要进行操作并返回数据。

  1. 调用你要测试的RestPriceService的实例sutTODO
  2. 模拟restTemplate好的
  3. 给这个模拟起一个名字,让它像restTemplateMock一样突出:TODO
  4. 设置为sutOK
  5. 使用when(restTemplateMock.exchange(...).thenReturn(r)TODO
  6. 致电sut.getPriceRow待办事项
  7. 验证此调用返回的RestPriceRow 是否正确:TODO
  8. 验证restTemplateMockTODO

编辑:

如果你想阅读一本非常关于不同形式的单元测试的好书,我可以推荐XUnit Test Patterns

【讨论】:

  • 很好,首先感谢您的快速回复。但我对第 5 点有疑问:交换调用是我要测试的方法的一部分,我认为更改服务中测试的代码不会很好。我在这里错过了什么吗?
  • 也许我没有很好地解释自己。 getPriceRow 方法不是测试类的一部分,是我正在测试的服务中的一种方法
  • 在您的代码中,getPriceRow 是 REST client 的一种方法。如果你想在没有真正的 REST 服务的情况下测试这个客户端的行为,你必须模拟你想要测试的代码调用的所有协作者的方法。
  • 抱歉坚持,但我无法让它工作。在设置上,我正在模拟 RestTemplate 并将其设置为服务 (RestPriceServiceImpl)。然后我使用“when(restPriceService.getPriceRow("100","200","16")).thenReturn(r);"。 getPriceRow 使用交换。所以我想我不能在交易所使用when.thenReturn
  • 不要在像 when 这样的 Mockito 方法中使用 restPriceServicerestPriceService 是您测试的,而不是所谓的。我建议尝试使用 Mockito 的简单示例来掌握它。
【解决方案2】:

所以这里有两个问题。如果您想测试 REST 接口,即进行调用并查看结果并进行检查,我建议使用 Jersey 测试框架。它在测试服务器上运行,可以节省大量工作。 (假设您使用的是泽西岛。)

http://jersey.java.net/nonav/documentation/latest/test-framework.html

但是如果你只想测试服务层,你可以写普通的junit测试。

【讨论】:

  • 这是一个关于单元测试的问题,而不是关于集成测试的问题。在单元测试中,不会进行远程调用。
猜你喜欢
  • 1970-01-01
  • 2020-06-06
  • 1970-01-01
  • 1970-01-01
  • 2012-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多