我正在尝试在一个javamaven项目(而不是springboot项目)中编写junit 5代码,它调用API并提取响应并创建文件。但是当我试图模拟API调用时,junit仍然调用实际的API,这不是我们想要的行为。有人可以帮助确定这里的问题吗?
我按照这个链接写下面的单元测试How to mock HttpClient's send method in junit 5?
实际服务代码-
public class MyService {
public void create(String apiHost, String firstPage) {
HttpClient httpClient = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.connectTimeout(Duration.ofSeconds(30))
.build();
HttpRequest httpRequest = getHttpRequest(apiHost, firstPage);
MyResponse myResponse = invokeApi(httpClient, httpRequest);
List<ResponseData> responseDataList = new ArrayList<>(myResponse.getData());
while (null != myResponse.getLinks().getNext()) {
myResponse = invokeApi(httpClient, getHttpRequest(apiHost, invokeApi.getLinks().getNext()));
locationDetailsList.addAll(invokeApi.getData());
}
createFile(fileName, responseDataList);
}
private HttpRequest getHttpRequest(String apiHost, String pageUri) {
return HttpRequest.newBuilder()
.header("Content-Type", "application/json")
.GET()
.uri(URI.create(apiHost + pageUri))
.build();
}
@SneakyThrows
MyResponse invokeApi(HttpClient httpClient, HttpRequest httpRequest) {
HttpResponse<Supplier<MyResponse>> result = httpClient.send(httpRequest, new JsonBodyHandler<>(MyResponse.class));
return result.body().get();
}
@SneakyThrows
void createFile(String fileName, List<ResponseData> responseDataList) {
Path filePath = Paths.get("test/path" + fileName);
Files.createFile(filePath);
Files.writeString(filePath, header + System.lineSeparator(), StandardOpenOption.APPEND);
for (ResponseData responseData : responseDataList) {
Files.writeString(filePath, responseData + System.lineSeparator(), StandardOpenOption.APPEND);
}
}
第5号代码-
class MyServiceTests {
@InjectMocks
private MyService myService;
@Mock
private HttpClient httpClient;
@Mock
HttpResponse<Object> httpResponse;
@Mock
private HttpRequest request;
@BeforeEach
void setUp() {
initMocks(this);
httpClient = mock(HttpClient.class);
httpResponse = mock(HttpResponse.class);
}
@Test
void testSendMessage() throws Exception {
MyResponse myResponse=new MyResponse();
when(httpClient.send(any(),any())).thenReturn(httpResponse);
when(myService.invokeApi(httpClient,request)).thenReturn(myResponse);
myService.create("https://test.com", "/v1/test?page_size=100");
verify(httpClient).send(request, HttpResponse.BodyHandlers.ofString());
}
}
在上面的junit代码中,当执行“myService.createmyMnt”时,它实际上尝试调用https://test.com,而不是模拟调用。
1条答案
按热度按时间lnvxswe21#
你面临这个问题是因为你模拟了两次相同的依赖。我的意思是:
然后在每个你再次嘲笑你的依赖
我建议选择你需要的方法,不要模仿2次。在这里,你是嘲笑和使用@InjectMocks。我们还需要添加注解@ExtendWith(MockitoExtension.class),这将处理initMocks(this),我们不需要添加它(这个注解有助于正确注入模拟)。
或使用构造函数注入,如:
请试试这个: