【发布时间】:2021-10-19 09:58:28
【问题描述】:
我正在开发具有微服务架构的 Spring Boot 项目。我有一个通过 RestTemplate 与另一个服务通信的服务。 HttpDataClient.java 类正在向外部服务发送 dataId 并且应该收到一些响应。对于我的测试,我应该测试 RestTemplate 并检查我是否得到了良好的响应。
这是我需要测试的课程:
public class HttpDataClient implements DataClient{
private final static Logger LOGGER = LoggerFactory.getLogger(HttpDataClient.class);
private final RestTemplate restTemplate;
private final ObjectMapper objectMapper = new ObjectMapper();
public HttpDataClient(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@Override
public DataResponse getData(String dataId) {
try{
JsonNode node = restTemplate.exchange(
String.format("/data/{0}", dataId),
HttpMethod.POST,
new HttpEntity<>(buildRequest(dataId), headers()),
JsonNode.class
).getBody();
return dataResponse(node);
}catch (HttpStatusCodeException e) {
String msg = String.format(
"Error getting data for dataId: {0}",
dataId,
e.getStatusCode(),
e.getResponseBodyAsString());
LOGGER.error(msg);
return dataResponse.failed();
}
}
private MultiValueMap<String, String> headers() {
final LinkedMultiValueMap<String, String> mv = new LinkedMultiValueMap<>();
mv.set(HttpHeaders.CONTENT_TYPE, "application/json");
return mv;
}
private DataResponse dataResponse(JsonNode node) {
return DataResponse.dataResponse(
asString(node, "dataId"),
asString(node, "author"),
asString(node, "authorDataId"),
asString(node, "serverSideDataId")
);
}
private JsonNode buildRequest(String dataId) {
ObjectNode root = objectMapper.createObjectNode();
root.put("dataId", dataId);
return root;
}
}
测试类如下所示:
@RunWith(MockitoJUnitRunner.class)
public class HttpDataServiceTest {
@Mock
RestTemplate restTemplate;
@InjectMocks
private HttpDataService httpDataService;
@Test
public void getData() {
httpDataService.getData("gameIdTest");
Mockito
.when(restTemplate.exchange(
ArgumentMatchers.eq("/game/IdTest"),
ArgumentMatchers.eq(HttpMethod.POST),
ArgumentMatchers.any(),
ArgumentMatchers.<Class<DataResponse>>any()))
.thenReturn(new ResponseEntity<>(HttpStatus.ACCEPTED));
}
}
当我运行测试时,我得到一个 NullPointerException
java.lang.NullPointerException at com.example.gamedata.HttpDataService.getData(HttpDataService.java:37) at com.example.data.HttpDataServiceTest.getData(HttpDataServiceTest.java:36) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
我在这里错过了什么?
【问题讨论】:
-
您的模拟场景与您的代码不匹配。
/game/idTest/->/data/{0}这些完全不同,它返回JsonNode而不是DataResponse。并且您的模拟应该在您实际调用该方法之前进行。 -
你能否在我的代码中给我一个例子我不确定我是否理解。我应该在 HttpDataServiceClass 中用 DataResponse 更改 JsonNode 吗?
-
为什么要更改代码?是你的测试是错误的(假设现在你的代码是正确的)。
-
是的,是的,我就是这么想的。你有什么改变的建议?我是测试的初学者,所以我全神贯注:)
-
对于初学者来说,最好阅读一本关于 Junit 和 Mockito 的书,而不是反复试验。假设您的代码是正确的,您的 mockito 模拟应该与该调用匹配,但目前不匹配。我已经在我的第一篇文章中解释了哪里出了问题,因此你需要改变什么。
标签: java spring-boot unit-testing resttemplate