gpt4 book ai didi

java - Mockito 无法模拟 Rest API 调用

转载 作者:行者123 更新时间:2023-12-02 09:27:40 26 4
gpt4 key购买 nike

使用 Mockito 测试 REST API,总是出现错误。我试图 mock

apiClient.execute(buildApiCall("POST", url, reqBody), localVarReturnType);

但是没有任何效果,这里的任何帮助将不胜感激

待测系统

public CreateUser createUser(String fullname, String username, String password, String departmentName) {
String url = "/api/v1/account/?apikey=" + apiKey;
String randomUsername = generateRandomString(20);
CreateUser payload = new CreateUser();
payload.setFullName(fullname);
payload.setUsername(username);
payload.setPassword(generatePassword((password != null) ? password : generatePassword(randomUsername)));
payload.setEmail(username + "@qstack.com");
payload.setDepartmentName(departmentName);

RequestBody reqBody = apiClient.serialize(payload, "application/json");
Type localVarReturnType = new TypeToken<CreateUser>() { }.getType();
ApiResponse<CreateUser> responseFromApiClient = apiClient.execute(buildApiCall("POST", url, reqBody), localVarReturnType);
return responseFromApiClient.getData();
}

public Call buildApiCall(String method, String url, RequestBody reqBody) {
String signature = null;
try {
signature = generateSignature(url);
} catch (SignatureException e) {
e.printStackTrace();
}

return apiCall(method, url, signature, reqBody);
}

private Call apiCall(String method, String url, String signature, RequestBody reqBody) {
String baseUri = "http://localhost:8002";
String finalUrl = baseUri + url + "&signature=" + signature;
final Request.Builder reqBuilder = new Request.Builder().url(finalUrl);
reqBuilder.header("Accept", "*/*");
reqBuilder.header("Content-Type", "application/json");

return httpClient.newCall(reqBuilder.method(method, reqBody).build());
}

单元测试代码

 @Test
public void testQuery() {
String jsonResponse = "{\n" +
" \"address_one\": \"\",\n" +
" \"address_three\": \"\",\n" +
" \"address_two\": \"\",\n" +
" \"country_code\": \"\",\n" +
" \"cs_domain_id\": null,\n" +
" \"date_joined\": \"2019-10-02T19:12:55.722764\",\n" +
" \"disable_personal_account\": false,\n" +
" \"email\": \"username123@qstack.com\",\n" +
" \"first_name\": \"username123\",\n" +
" \"id\": 73,\n" +
" \"is_reseller\": false,\n" +
" \"is_superuser\": false,\n" +
" \"is_verified\": true,\n" +
" \"last_login\": null,\n" +
" \"last_name\": \"\",\n" +
" \"paywall\": true,\n" +
" \"postal_code\": \"\",\n" +
" \"projects\": [],\n" +
" \"reference_number\": \"\",\n" +
" \"reseller_id\": 1,\n" +
" \"reseller_name\": \"ROOT\",\n" +
" \"reseller_rights\": [],\n" +
" \"resource_uri\": \"/api/v1/account/73/\",\n" +
" \"saml\": false,\n" +
" \"state\": 0,\n" +
" \"status\": \"enabled\",\n" +
" \"surname\": \"\",\n" +
" \"username\": \"username123\",\n" +
" \"uuid\": \"9f79e45f-9cc8-40e8-b5c6-bd406893bdd6\"\n" +
"}";

Gson gson = new GsonBuilder().create();
CreateUser response = gson.fromJson(jsonResponse, CreateUser.class);
ApiResponse<CreateUser> responseFromApiClient = new ApiResponse<>(200, null, response);

OkHttpClient httpClientMock = mock(OkHttpClient.class);
ApiClient apiClientMock = mock(ApiClient.class);

when(apiClientMock.serialize(payload, "application/json")).thenReturn(any());
GqConsoleApiClient g = new GqConsoleApiClient(httpClientMock, apiClientMock);
Mockito.<ApiResponse<? extends CreateUser>>when(apiClientMock.execute(any(), any())).thenReturn(responseFromApiClient);
g.createUser("jon", "jon", "jon", "ROOT");

Assertions.assertEquals("jon", responseFromApiClient.getData().getUsername());
}

在查看 IntelliJ 的覆盖率输出时,我设法到达倒数第二行

ApiResponse responseFromApiClient = apiClient.execute(buildApiCall("POST", url, reqBody), localVarReturnType);

但是测试抛出异常

java.lang.IllegalArgumentException: method POST must have a request body.

at com.squareup.okhttp.Request$Builder.method(Request.java:259)
at com.greenqloud.netappstats.collector.metrics.gqconsole.api.GqConsoleApiClient.apiCall(GqConsoleApiClient.java:136)
at com.greenqloud.netappstats.collector.metrics.gqconsole.api.GqConsoleApiClient.buildApiCall(GqConsoleApiClient.java:126)
at com.greenqloud.netappstats.collector.metrics.gqconsole.api.GqConsoleApiClient.createUser(GqConsoleApiClient.java:82)
at com.greenqloud.netappstats.collector.metrics.gqconsole.api.MockitoTest.testQuery(MockitoTest.java:87)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:513)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:170)
at org.junit.jupiter.engine.execution.ThrowableCollector.execute(ThrowableCollector.java:40)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:166)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:113)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:58)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:113)
at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$2(HierarchicalTestExecutor.java:121)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:121)
at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$2(HierarchicalTestExecutor.java:121)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:121)
at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:55)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:43)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:170)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:154)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:90)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

在添加新的模拟调用后编辑了新错误,请参阅测试函数。

at io.swagger.cv.client.ApiClient.execute(ApiClient.java:840)
at com.greenqloud.netappstats.collector.metrics.gqconsole.api.MockitoTest.testQuery(MockitoTest.java:106)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:513)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:170)
at org.junit.jupiter.engine.execution.ThrowableCollector.execute(ThrowableCollector.java:40)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:166)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:113)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:58)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:113)
at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$2(HierarchicalTestExecutor.java:121)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)

这个错误指向这个函数

public <T> ApiResponse<T> execute(Call call, Type returnType) throws ApiException {
try {
Response response = call.execute();
T data = handleResponse(response, returnType);
return new ApiResponse<T>(response.code(), response.headers().toMultimap(), data);
} catch (IOException e) {
throw new ApiException(e);
}
}

最佳答案

你不是在 mock 这个电话

apiClient.serialize(payload, "application/json");

因此可能返回 null

不要忘记 apiClient 是一个模拟

ApiClient apiClientMock = mock(ApiClient.class);

而且您只是在模拟 execute 方法。

Mockito.<ApiResponse<? extends CreateUser>>when(apiClientMock.execute(any(), any())).thenReturn(responseFromApiClient);

通过模拟 serialize 方法来修复此问题。

关于java - Mockito 无法模拟 Rest API 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58222458/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com