我的应用程序序列化了各种模型,并通过HTTP请求将它们发送给第三方。
我想根据集成测试将请求主体反序列化为该模型或那个模型,然后对其进行断言。看起来有些人可能实现了自己的RequestMatcher
或只是对字符串进行了断言,但是这两个选项似乎都很脏。如果我实现自己的RequestMatcher
,则必须为主体可以(并且有很多)的每种模型实现不同的RequestMatcher
。
如果我可以在请求正文中反序列化json并在声明性匹配内容之外执行我想做的事情,那将是很好的选择。
类似这样的东西:
BodyCaptor captor = new BodyCaptor(); // I made this up
MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).ignoreExpectOrder(true).build();
mockServer
.expect(MockRestRequestMatchers.requestTo(testBaseUri + testApiPath))
.andExpect(method(HttpMethod.POST))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andCaptureBody(captor)
.andRespond(MockRestResponseCreators.withSuccess());
MyModel mymodel = objectMapper.deserialize(captor.getValue())
assertThat(mymodel.getWhateverProperty()).isEqualTo(5)
....
像这样可能吗?我有什么选择?
答案 0 :(得分:1)
您可以使用MockRestRequestMatchers.jsonPath来验证属性,以验证json属性及其值
mockServer
.expect(MockRestRequestMatchers.requestTo(testBaseUri + testApiPath))
.andExpect(method(HttpMethod.POST))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(MockRestRequestMatchers.jsonPath("$.property", Matchers.equalToIgnoringCase("value")))
.andRespond(MockRestResponseCreators.withSuccess());
答案 1 :(得分:0)
我最终写了一个使用杰克逊ggplot(dataset2, aes(x=Region, y= male)) + geom_bar(stat='identity')
并拿下RequestMatcher
的单个ObjectMapper
。这样,我可以反序列化为expectedObject
的类型,并通过字段比较来做一个字段。
expectedObject
现在我可以在测试中执行以下操作:
public class MyRequestMatcher implements RequestMatcher {
private static final Logger LOG = LoggerFactory.getLogger(MyRequestMatcher.class);
private Object expectedPayload;
private ObjectMapper objectMapper;
public MyRequestMatcher (Object expectedPayload, ObjectMapper objectMapper) {
this.expectedPayload = expectedPayload;
this.objectMapper = objectMapper;
}
@Override
public void match(ClientHttpRequest clientHttpRequest) throws IOException, AssertionError {
byte[] requestBodyBytes = ((ByteArrayOutputStream)clientHttpRequest.getBody()).toByteArray();
String requestBody = new String(requestBodyBytes, StandardCharsets.UTF_8);
Object actualPayload = objectMapper.readValue(requestBody, expectedPayload.getClass());
// do this in a try catch so we can log the meaningful message from our assertion
// library before rethrowing - otherwise it gets swallowed by mockServer
try {
assertThat(actualPayload).isEqualToComparingFieldByField(expectedPayload)
} catch (AssertionError error) {
LOG.error(error.getMessage());
throw error;
}
}
}
答案 2 :(得分:0)
如果你只需要一次就可以使用 lambda
ByteArrayOutputStream bos = new ByteArrayOutputStream();
...
.andExpect(clientHttpRequest -> bos.write(((ByteArrayOutputStream) clientHttpRequest.getBody()).toByteArray()))
...