Micronaut HTTP 客户端 - 反序列化通用类型 - 用于 API 测试
Micronaut HTTP Client - Deserialize generic type - For API Testing
对于 API 测试,我必须使用 io.micronaut.http.client.HttpClient
解析请求的响应
我更喜欢使用下面给出的格式。
Response<User> response =
client.toBlocking().retrieve(HttpRequest.POST("/", user), Response.class);
但是它不起作用。尝试从响应中获取用户时出现类型转换错误
User user = response.getUser();
目前我正在使用 ObjectMapper (Jackson),如下所示,
String response = client.toBlocking().retrieve(HttpRequest.POST("/", user), String.class);
ObjectMapper objectMapper = new ObjectMapper();
Response<User> response = objectMapper.readValue(response, new TypeReference<Response<User>>() {});
有什么方法可以直接使用 TypeReference 和 HttpClient 检索方法吗?或者以任何其他方式将通用 class 类型与 HttpClient.
一起使用
其他有用信息
// Response generic class
class Response<T> {
T data;
....
}
响应示例
{
"data": {
"name":"sample"
},
"message": "Success"
}
您有几个选择:
如果您只需要那个 User
对象实例,您可以通过 retrieve()
方法来实现,其中第二个参数是域 class(User
在您的情况下)然后您可以根据需要使用 user
变量:
User user = client.toBlocking().retrieve(HttpRequest.POST("/", user), User.class);
assertThat(user)
.isNotNull()
.extracting(User::getName)
.isEqualTo("sample");
如果您还需要响应对象(例如能够检查响应代码),那么您应该使用 exchange()
方法,然后通过调用 body()
方法获取 User
实例关于那个回应:
HttpResponse<User> response = client.toBlocking()
.exchange(HttpRequest.POST("/", user), User.class);
assertThat(response)
.isNotNull()
.extracting(HttpResponse::body)
.extracting(User::getName)
.isEqualTo("sample");
Update:当您需要使用通用 class 作为响应时,您必须使用 Argument.of()
作为 [=15] 的第二个参数=] 和 exchange()
方法,您可以在其中指定响应泛型 class 及其类型参数。看例子:
Response<User> response = client.toBlocking()
.retrieve(HttpRequest.POST("/", user), Argument.of(Response.class, User.class));
assertThat(response)
.isNotNull()
.extracting(Response::getData)
.extracting(User::getName)
.isEqualTo("sample");
如果你在没有 Argument.of()
的情况下这样做,那么它会将 data
属性 转换为 LinkedHashMap
而不是 User
和这个:
Response<User> response = client.toBlocking().retrieve(HttpRequest.POST("/", user), Response.class);
response.getData().getName();
... 会抛出 ClassCastException
:
java.lang.ClassCastException: class java.util.LinkedHashMap cannot be
cast to class my.app.domain.User (java.util.LinkedHashMap is in module
java.base of loader 'bootstrap'; my.app.domain.User.User is in unnamed
module of loader 'app')
作为一个非常简单的替代方案:当您的响应是 JSON 时,您总是可以简单地将它们反序列化为 Map.class
。快速简单。当然你没有类型安全。
对于 API 测试,我必须使用 io.micronaut.http.client.HttpClient
解析请求的响应我更喜欢使用下面给出的格式。
Response<User> response =
client.toBlocking().retrieve(HttpRequest.POST("/", user), Response.class);
但是它不起作用。尝试从响应中获取用户时出现类型转换错误
User user = response.getUser();
目前我正在使用 ObjectMapper (Jackson),如下所示,
String response = client.toBlocking().retrieve(HttpRequest.POST("/", user), String.class);
ObjectMapper objectMapper = new ObjectMapper();
Response<User> response = objectMapper.readValue(response, new TypeReference<Response<User>>() {});
有什么方法可以直接使用 TypeReference 和 HttpClient 检索方法吗?或者以任何其他方式将通用 class 类型与 HttpClient.
一起使用其他有用信息
// Response generic class
class Response<T> {
T data;
....
}
响应示例
{
"data": {
"name":"sample"
},
"message": "Success"
}
您有几个选择:
如果您只需要那个 User
对象实例,您可以通过 retrieve()
方法来实现,其中第二个参数是域 class(User
在您的情况下)然后您可以根据需要使用 user
变量:
User user = client.toBlocking().retrieve(HttpRequest.POST("/", user), User.class);
assertThat(user)
.isNotNull()
.extracting(User::getName)
.isEqualTo("sample");
如果您还需要响应对象(例如能够检查响应代码),那么您应该使用 exchange()
方法,然后通过调用 body()
方法获取 User
实例关于那个回应:
HttpResponse<User> response = client.toBlocking()
.exchange(HttpRequest.POST("/", user), User.class);
assertThat(response)
.isNotNull()
.extracting(HttpResponse::body)
.extracting(User::getName)
.isEqualTo("sample");
Update:当您需要使用通用 class 作为响应时,您必须使用 Argument.of()
作为 [=15] 的第二个参数=] 和 exchange()
方法,您可以在其中指定响应泛型 class 及其类型参数。看例子:
Response<User> response = client.toBlocking()
.retrieve(HttpRequest.POST("/", user), Argument.of(Response.class, User.class));
assertThat(response)
.isNotNull()
.extracting(Response::getData)
.extracting(User::getName)
.isEqualTo("sample");
如果你在没有 Argument.of()
的情况下这样做,那么它会将 data
属性 转换为 LinkedHashMap
而不是 User
和这个:
Response<User> response = client.toBlocking().retrieve(HttpRequest.POST("/", user), Response.class);
response.getData().getName();
... 会抛出 ClassCastException
:
java.lang.ClassCastException: class java.util.LinkedHashMap cannot be cast to class my.app.domain.User (java.util.LinkedHashMap is in module java.base of loader 'bootstrap'; my.app.domain.User.User is in unnamed module of loader 'app')
作为一个非常简单的替代方案:当您的响应是 JSON 时,您总是可以简单地将它们反序列化为 Map.class
。快速简单。当然你没有类型安全。