如何为休息交换写Mockito测试

时间:2018-06-14 19:35:27

标签: java unit-testing junit mocking mockito

  
    

这是我进行HttP调用以发送消息的方式。想知道单元测试的最佳方法

  
public void httCall(String msgToSend) {

    try {
        ResponseEntity <String> response = rest.exchange(URL, HttpMethod.POST,new HttpEntity<>(msgToSend), String.class);
        LOG.info("sent to {}  response {} {}",msgToSend,response.getStatusCode(), response.getBody());
        } catch (HttpClientErrorException e) {
              LOG.error("error calling  ", e);
                    throw e;
            }
    }

1 个答案:

答案 0 :(得分:1)

从字面上看,您需要验证是否使用正确的参数调用了rest.exchange。您必须模拟RestTemplate,注入它,并验证方法是否按预期调用。在这种情况下,我认为您实际上必须捕获参数,因为msgToSend被包裹在新的HttpEntity中。它有点棘手,因为我们还必须模拟返回的ResponseEntity,以便与它的交互不会抛出NullPointerException

@Test
public void testMessageSent(){
   RestTemplate template = Mockito.mock(RestTemplate.class);
   YourClass toTest = new YourClass(template);
   ResponseEntity<String> response = new ResponseEntity<String>(HttpStatus.OK, "Hello World");
   Mockito.when(template.exchange(Mockito.anyString(),  Mockito.any(),  Mockito.any(HttpEntity.class),  Mockito.<Class<?>> any())).thenReturn(response);

yourClass.httCall("Hello World");

ArgumentCaptor<String> urlCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<HttpMethod> methodCaptor = ArgumentCaptor.forClass(HttpMethod.class);
ArgumentCaptor<HttpEntity> entityCaptor = ArgumentCaptor.forClass(HttpEntity.class);
ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class);

Mockito.verify(template.exchange(urlCaptor, methodCaptor, entityCaptor, classCaptor);

Assert.assertEquals("expectedUrl", urlCaptor.getValue());
Assert.assertEquals(HttpMethod.POST, methodCaptor.getValue());
Assert.assertEquals("Hello World", entityCaptor.getValue().getBody());
Assert.assertEquals(String.class, classCaptor.getValue());

请注意,您可能必须使用RestOperations接口而不是RestTemplate类。我依旧记得Mockito无法模仿RestTemplate但我现在主要使用Spock。

对于一个非常简单的方法来说,这是一些先进的Mockito,但是我发现方法中的棘手错误比这更简单。