【问题标题】:How to fix the null value response of RestTemplate.exchange in a Mockito Test?如何在 Mockito 测试中修复 RestTemplate.exchange 的空值响应?
【发布时间】:2018-01-22 06:29:28
【问题描述】:

我的服务类在下面,然后是它的测试 -

@Service
public class MyServiceImpl implements MyService {

        @Autowired
        private RestTemplate restTemplate;

        @Override
        public StudentInfo getStudentInfo(String name) {
            HttpHeaders headers = new HttpHeaders();
            headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);

            HttpEntity entity = new HttpEntity(headers);

            StudentInfo student = null;

            URI uri = new URI("http:\\someurl.com");             

           ResponseEntity<String> responseEntity = restTemplate.exchange(uri,
                        HttpMethod.GET, entity,
                        String.class);

           if (responseEntity.getStatusCode().equals(HttpStatus.NO_CONTENT)) {
                   throw new Exception("Student absent");
            }else {
              ObjectMapper mapper = new ObjectMapper();
              StudentInfo student = mapper.readValue(responseEntity.getBody(), StudentInfo.class);

           }

            return student;
        }
    }

测试类:在下面的测试类中,我在调试时看到 ResponseEntity 对象为空,这会导致 NPE。

@RunWith(MockitoJUnitRunner.class)
public class MyServiceImplTest {

    @InjectMocks
    private MyService service = new MyServiceImpl();

    @Mock
    private RestTemplate restTemplate;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testStudentGetterResponse() {

        ResponseEntity<String> mockEntity = Mockito.spy(new ResponseEntity({"id" : 1, "name" : "Rutzen"}, HttpStatus.OK));

        doReturn(mockEntity).when(restTemplate).exchange(any(URI.class), any(HttpMethod.class), any(ResponseEntity.class),
                any(Class.class));

        StudentInfo info = service.getStudentInfo("testuser");

        Assert.assertNotNull(info);


    }

}

当我调试测试时,我在主服务类的以下行中得到了 responseEntity 的空值 -

 ResponseEntity<String> responseEntity = restTemplate.exchange(uri,
                        HttpMethod.GET, entity,
                        String.class);

【问题讨论】:

    标签: spring-boot junit mockito spring-test spring-boot-test


    【解决方案1】:

    这条指令...

    doReturn(mockEntity).when(restTemplate).exchange(
        any(URI.class), 
        any(HttpMethod.class), 
        any(ResponseEntity.class),              
        any(Class.class)
    );
    

    ... 应替换为:

    doReturn(mockEntity).when(restTemplate).exchange(
        any(URI.class), 
        any(HttpMethod.class), 
        any(HttpEntity.class),              
        any(Class.class)
    );
    

    因为getStudentInfo() 创建了HttpEntity 的实例(不是 ResponseEntity),然后将其传递给restTemplate.exchange() 调用。

    【讨论】:

    • 这没有帮助,同样的问题
    • 您确定您看到的是 *same 问题吗?我抓住了您的代码并重现了该问题,然后通过进行我在回答中建议的更改来修复它。在这样做的同时,我注意到我还必须整理代码中的一些其他小项目(例如,在 URI 构造函数中使用反斜杠而不是正斜杠)。如果您现在使用any(HttpEntity.class),也许错误现在来自其他地方?
    • 发现了问题——这实际上很奇怪。当我编辑代码使 responseEntity 模拟设置在同一行而不是多行时,它开始工作
    • @glytching 非常感谢,我在 3 天内找到了这个答案。
    • @Righto 您应该在答案中添加它。同样的事情发生在我身上,我在阅读了你的评论后修复了它。谢谢
    【解决方案2】:

    因为接受的答案是正确的。我正在为已经接受的答案添加一些内容。

    这似乎有点奇怪,但我通过查看接受的答案解决了这个问题,并且评论是由提出问题的用户添加的。

    替换这个

    doReturn(mockEntity).when(restTemplate).exchange(
        any(URI.class), 
        any(HttpMethod.class), 
        any(ResponseEntity.class),              
        any(Class.class)
    );
    

    与,

    doReturn(mockEntity).when(restTemplate).exchange(
        any(URI.class), 
        any(HttpMethod.class), 
        any(HttpEntity.class),              
        any(Class.class)
    );
    

    如果您仍然收到错误,请不要使用多行。只使用一行并像下面这样替换它。

    doReturn(mockEntity).when(restTemplate).exchange(any(URI.class), any(HttpMethod.class), any(HttpEntity.class), any(Class.class)
    );
    

    【讨论】:

    • 最后一个建议是难以置信的。谢谢...
    【解决方案3】:
     ResponseEntity<String> responseEntity = restTemplate.exchange(uri,
                            HttpMethod.GET, entity,
                            String.class);
    

    String[]的情况下我不会工作

    喜欢

    ResponseEntity<String[]> responseEntity = restTemplate.exchange(uri,
                            HttpMethod.GET, entity,
                            String[].class);
    

    【讨论】:

      猜你喜欢
      • 2021-04-27
      • 2021-06-04
      • 1970-01-01
      • 2022-07-06
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 2023-01-30
      • 2021-04-16
      相关资源
      最近更新 更多