【问题标题】:mocking resttemplate exchange always returns null模拟 resttemplate 交换总是返回 null
【发布时间】:2019-08-30 14:53:40
【问题描述】:

我试图通过 mockito 模拟一个 restTemplate.exchange 方法,但无论我通过 mock 返回什么,它总是返回一个空值,即使我抛出异常:

这是实际代码:

ResponseEntity<List<LOV>> response = restTemplate.exchange(url, GET, null,new ParameterizedTypeReference<List<LOV>>() {});

模拟代码:

 ResponseEntity<List<LOV>> mockResponse = new ResponseEntity<List<LOV>>(mockLovList() ,HttpStatus.ACCEPTED);

Mockito.when(restTemplate.exchange(any(), eq(GET), any(), ArgumentMatchers.<ParameterizedTypeReference<List<LOV>>>any())).thenReturn(mockResponse);

交换模拟中的每个参数都是 ArgumentMatchers 类型, mockLovList() 返回一个 LOV 列表

它应该返回我模拟的任何东西,但它总是返回 null

【问题讨论】:

    标签: spring junit mockito resttemplate argument-matcher


    【解决方案1】:

    这是一个 RestTemplate.exchange() 模拟测试的工作示例:

    import org.junit.Assert;
    import org.junit.Test;
    import org.mockito.Mockito;
    import org.springframework.core.ParameterizedTypeReference;
    import org.springframework.http.HttpEntity;
    import org.springframework.http.HttpMethod;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.client.RestTemplate;
    
    import java.util.Arrays;
    import java.util.List;
    
    import static org.mockito.Mockito.*;
    
    public class MyTest {
    
        @Test
        public void testRestTemplateExchange() {
            RestTemplate restTemplate = mock(RestTemplate.class);
    
            HttpEntity<String> httpRequestEntity = new HttpEntity<>("someString");
    
            List<String> list = Arrays.asList("1", "2");
            ResponseEntity mockResponse = new ResponseEntity<>(list, HttpStatus.ACCEPTED);
            when(restTemplate.exchange(anyString(), any(), any(), any(ParameterizedTypeReference.class), any(Object[].class)))
                    .thenReturn(mockResponse);
    
    
            final ResponseEntity<List<String>> exchange = restTemplate.exchange("/someUrl", HttpMethod.GET, httpRequestEntity, new ParameterizedTypeReference<List<String>>() {
            });
    
            Assert.assertEquals(list, exchange.getBody());
    
        }
    
    }
    

    【讨论】:

    • 我在做同样的事情,但对我不起作用。我在另一个答案中评论了它在做 mockito.verify 时给出的错误
    • 当我在实际交换调用中有第 5 个参数时它可以工作..这个参数 any(Object[].class),但如果第 5 个参数在实际交换方法中为空,我没有通过真正交换中最后一个参数中的任何内容都只调用 4 个参数,我不需要它
    【解决方案2】:

    在设置或注入服务之前,您需要确保已初始化模拟。像这样-

    @Mock
    RestTemplate restTemplate;
    @Before
    public void init() {
        MockitoAnnotations.initMocks(this);
        userData = new UserService(restTemplate);
    }
    

    【讨论】:

    • 这其实是正确答案
    【解决方案3】:

    首先你可以使用验证方法调用是否正确

     Mockito.verify(restTemplate).exchange(any(), eq(GET), any(), any(ParameterizedTypeReference.class)))
    

    Mockito 显示了一个非常漂亮的输出,包括实际的方法调用。

    另外,您可以参考Deep StubbingTesting anonymous classes

    【讨论】:

    • 是的,这本身不起作用,它给出了 java.lang.reflect.InvocationTargetException
    • 需要但未调用:restTemplate.exchange( , GET, , );
    • 然而,这个模拟只有 1 次交互:restTemplate.exchange("url", GET, null, ParameterizedTypeReference>
    【解决方案4】:

    我遇到了同样的问题(至少有 2 个涉及这个问题),在寻找一个合理的答案后,我可以成功解决它。

    在我解释之前,我将分享 2 个对我有帮助的解释。 How do I mock a REST template exchange?Mocking RestTemplate.exchange() method gives null value

    所以,基本上,关键是每个涉及任何 RestTemplate 方法的测试用例都必须正确地给出每个参数。如果不行,Mockito 会失败并抛出这样的异常:

    org.mockito.exceptions.misusing.PotentialStubbingProblem

    或使用 NullPointerException 从 restTemplate.exchange 获取 ResponseEntity(这是你的情况)

    之前(我隐藏了一些实现。Mockito 抛出了异常)

    when(restTemplate.exchange(anyString(), any(HttpMethod.class), any(), 
                        ArgumentMatchers.<ParameterizedTypeReference<FilterBean>>any())).thenReturn(responseEntityFilterBean);
    

    Mockito 异常

    org.mockito.exceptions.misusing.PotentialStubbingProblem:严格 存根参数不匹配。请检查:

    • 此“交换”方法的调用: restTemplate.exchange( “/筛选”, 得到, , 类 br.com.test.bean.FilterBean ); -> 在 br.com.test.service.FilterService.getFilterStatus(FiltroService.java:60)
    • 具有以下具有不同参数的存根:
      1. restTemplate.exchange("", null, null, null);

    说明参数不对!

    更改我的代码解决了我的问题。

                    when(restTemplate.exchange(ArgumentMatchers.anyString(), 
                        ArgumentMatchers.any(HttpMethod.class),
                        ArgumentMatchers.any(), 
                        ArgumentMatchers.<Class<FilterBean>>any())).thenReturn(responseEntityFilterBean);
    

    在你的情况下,尝试这样做,它会解决:

            when(restTemplate.exchange(ArgumentMatchers.anyString(), 
                        ArgumentMatchers.any(HttpMethod.class),
                        ArgumentMatchers.any(), ArgumentMatchers.<Class<List<String>>>any())))
                .thenReturn(mockResponse);
    

    【讨论】:

      猜你喜欢
      • 2022-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-20
      • 1970-01-01
      • 1970-01-01
      • 2018-10-20
      相关资源
      最近更新 更多