Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在MockRestServiceServer中验证json请求正文_Java_Spring_Spring Boot - Fatal编程技术网

Java 如何在MockRestServiceServer中验证json请求正文

Java 如何在MockRestServiceServer中验证json请求正文,java,spring,spring-boot,Java,Spring,Spring Boot,我的应用程序序列化各种模型,并通过HTTP请求将它们发送给第三方 我希望根据集成测试将请求主体反序列化为这个或那个模型,然后对其进行断言。看起来有些人可能会实现他们自己的RequestMatcher,或者只是针对字符串进行断言,但这两个选项看起来都很脏。如果我实现了我自己的RequestMatcher,我就必须为主体可能是的每个模型实现一个不同的RequestMatcher 如果我可以在请求体中反序列化json,并在声明性匹配内容之外对其执行我想要的操作,那就太好了 大概是这样的: BodyCa

我的应用程序序列化各种模型,并通过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)
....

这样的事情可能吗?我的选项是什么?

您可以使用验证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());

最后,我编写了一个
请求匹配程序
,它使用了Jackson
对象映射器
,并获取了一个
预期对象
。通过这种方式,我可以反序列化到
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;
        }
    }
}
现在,我可以在测试中执行以下操作:

MyObject expectedPayload = new MyObject();
expectedPayload.setField1("expectedValueforField1");
expectedPayload.setField2("expectedValueforField2");

mockServer
    .expect(MockRestRequestMatchers
            .requestTo("http://myurl.com/mypath"))
    .andExpect(new MyRequestMatcher(expectedPayload, objectMapper))
    .andRespond(request -> {
        return MockRestResponseCreators.withSuccess().createResponse(request);
    });

如果你只需要它一次,你可以用一个lambda

ByteArrayOutputStream bos = new ByteArrayOutputStream();
...
.andExpect(clientHttpRequest -> bos.write(((ByteArrayOutputStream) clientHttpRequest.getBody()).toByteArray()))
...