【问题标题】:How to write mockito junit for Resttemplate exchange method如何为 Resttemplate 交换方法编写 mockito junit
【发布时间】:2015-08-30 13:20:19
【问题描述】:

如何为以下方法编写 mockito junit:

@Autowired
RestTemplate restTemplate;

ResponseEntity<?> execute(final String url, HttpMethod httpMethod,
                          HttpEntity<?> entityRequest,
                          String.class, 
                          Map<String, String> urlVariables){
    restTemplate.exchange(url, httpMethod, entityRequest, responseType, urlVariables);
}

请帮我写一下。

【问题讨论】:

  • 在这种情况下,您必须模拟其余模板。然后只需模拟方法调用:Mockito.when(restTemplate.exhange(...)).thenReturn(..)。有什么问题吗?
  • 不应该execute方法返回exchange结果吗?
  • 您要测试方法逻辑并模拟restTemplate结果吗?

标签: spring junit mockito resttemplate


【解决方案1】:
@RunWith(MockitoJUnitRunner.class)
public class ToTestTest {

  @InjectMocks
  private YourClass toTest;

  @Mock
  private RestTemplate template;

  @Test
  public void test() {
    toTest.execute(Mockito.anyString(), Mockito.any(), Mockito.any(), 
                   Mockito.any(), Mockito.any());

    Mockito.verify(template, Mockito.times(1))
                    .exchange(Mockito.anyString(),
                                    Mockito.<HttpMethod> any(),
                                    Mockito.<HttpEntity<?>> any(),
                                    Mockito.<Class<?>> any(),
                                    Mockito.<String, String> anyMap());
    }
 }

【讨论】:

  • 这很好地展示了 mockito 机制。详细信息:在 any 调用之前,您需要在类型转换周围加上括号 (...)
  • 但是您认为在YourClass 中不要创建new RestTemplate()
  • Mockito 为你创建一个 resttemplate 的模拟实例
  • Invalid use of argument matchers! 4 matchers expected, 1 recorded:
  • @ClaudioPomo 当然你不这样做new RestTemplate() - 这将是一个硬依赖,不能被嘲笑,应该在你的代码中避免(即使你根本不写测试)。
【解决方案2】:

我认为在这种情况下(使用RestTemplate 进行客户端REST 测试)最方便和最合适的方法是MockRestServiceServerSpring Testing 框架提供。

【讨论】:

    【解决方案3】:

    这取决于你想要什么。

    使用模拟的一种方法是更容易调用execute 方法。为此,您可以使用实际参数的模拟版本,例如HttpMethodHttpEntity。如果底层 exchange 方法需要这些参数的某些行为,您可能需要使用 mockito 的 when ... thenReturn 方法将其存根。

    一旦设置了这些模拟参数以便您可以调用 execute 方法,您将需要检查其结果是否正确。

    为了检查返回值,您可以使用传统的 JUnit 断言。

    此外,您可能想要检查与模拟对象的某些交互是否确实发生了。为此,您可以使用 mockito 的 verify 方法来检查,例如,某些 HttpEntity 方法实际上被调用了。

    从技术上讲,您还可以验证是否调用了其余模板的 exchange 方法。为此,您需要模拟 RestTemplate 并将模拟注入您的测试类中。然后您可以使用 mockito 的 verfiy 来检查 exchange 是否以正确的方式调用。这通常是明智的做法,尤其是在您的被测类中有更多方法要测试的情况下。不过,对于目前的execute 方法来说,这似乎有点矫枉过正。

    【讨论】:

      【解决方案4】:

      我曾经遇到过这样的错误。我找到了一个更可靠的解决方案。我也提到了对我有用的导入语句。下面这段代码完美地模拟了其余的模板。

      import org.mockito.Matchers;  
      import static org.mockito.Matchers.any;
      
          HttpHeaders headers = new Headers();
          headers.setExpires(10000L);     
          ResponseEntity<String> responseEntity = new ResponseEntity<>("dummyString", headers, HttpStatus.OK);
          when(restTemplate.exchange( Matchers.anyString(), 
                  Matchers.any(HttpMethod.class),
                  Matchers.<HttpEntity<?>> any(), 
                  Matchers.<Class<String>> any())).thenReturn(responseEntity);
      

      这里的“responseEntity”值不会为空,我们可以用它来完美地断言一个语句。

      【讨论】:

        猜你喜欢
        • 2018-05-15
        • 2020-11-23
        • 2018-03-04
        • 1970-01-01
        • 1970-01-01
        • 2021-11-17
        • 1970-01-01
        • 1970-01-01
        • 2015-03-08
        相关资源
        最近更新 更多