如何在 Mockito 测试中修复 RestTemplate.exchange 的空值响应?
Posted
技术标签:
【中文标题】如何在 Mockito 测试中修复 RestTemplate.exchange 的空值响应?【英文标题】:How to fix the null value response of RestTemplate.exchange in a Mockito Test? 【发布时间】: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);
【问题讨论】:
【参考方案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);
【讨论】:
以上是关于如何在 Mockito 测试中修复 RestTemplate.exchange 的空值响应?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Mockito 和 JUnit 在 Spring Boot 中测试 POST 方法