测试Spring Boot RestTemplate客户端的JSON映射

Tho*_*sen 5 java junit resttemplate spring-boot

我有一个不受控制的REST API(由另一个遥远的团队提供),我需要从Spring Boot应用程序中使用它。

目前,我想针对我的RestTemplate调用所产生的请求(而不是响应)完全对应于远程端的期望编写测试。我有一个示例JSON代码段,我想从我的代码中复制-给定与示例代码相同的参数,我应该在请求正文中得到一个等效的JSON代码段,然后我想对其进行分析以确定。

到目前为止,我的想法是让RestTemplate在我的控制下使用服务器,然后捕获JSON请求。显然MockRestServiceServer,这是一个不错的选择。

这是正确的方法吗?如何配置MockRestServiceServer允许我执行此操作?

g00*_*00b 6

如果仅对验证JSON映射感兴趣,则始终可以ObjectMapper直接使用Jackson的方法,并使用JSONassert之类的库来验证对象结构是否匹配,以验证序列化的字符串是否与预期结果匹配。例如:

@Autowired
private ObjectMapper objectMapper;
private Resource expectedResult = new ClassPathResource("expected.json");

@Test
public void jsonMatches() {
    Foo requestBody = new Foo();
    String json = objectMapper.writeValueAsString(requestBody);
    String expectedJson = Files
        .lines(expectedResult.getFile())
        .collect(Collectors.joining());
    JSONAssert.assertEquals(expectedJson, json, JSONCompareMode.LENIENT);
}
Run Code Online (Sandbox Code Playgroud)

该测试仅用于ObjectMapper验证JSON映射,因此,您甚至可以执行此操作而无需在测试中实际引导Spring引导(这可能会更快)。不利的一面是,如果您使用的是与杰克逊不同的框架,或者RestTemplate更改了其实现,则该测试可能会过时。


另外,如果您对验证完整的请求是否匹配(URL,请求方法,请求正文等)感兴趣,则可以使用MockRestServiceServer前面提到的方法。可以通过在@SpringBootTest测试中添加注释,自动装配RestTemplate和调用服务来完成此操作RestTemplate,例如:

@RunWith(SpringRunner.class)
@SpringBootTest
public class FooServiceTests {
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private FooService fooService; // Your service

    private MockRestServiceServer server;

    @Before
    public void setUp() {
        server = MockRestServiceServer.bindTo(restTemplate).build();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用以下方法设置测试:

@Test
public void postUsesRestTemplate() throws IOException, URISyntaxException {
    Path resource = Paths.get(getClass().getClassLoader().getResource("expected-foo.json").toURI());
    String expectedJson = Files.lines(resource).collect(Collectors.joining());
    server.expect(once(), requestTo("http://example.org/api/foo"))
        .andExpect(method(HttpMethod.POST))
        .andExpect(MockRestRequestMatchers.content().json(expectedJson))
        .andRespond(withSuccess());
    // Invoke your service here
    fooService.post();
    server.verify();
}
Run Code Online (Sandbox Code Playgroud)