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

标签 java spring-boot junit resttemplate

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

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

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

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

最佳答案

如果您只对验证 JSON 映射感兴趣,您始终可以直接使用 Jackson 的 ObjectMapper 并通过使用像 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);
}

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


或者,如果您有兴趣验证完整请求是否匹配(URL、请求方法、请求正文等),您可以使用您提到的 MockRestServiceServer。这可以通过将 @SpringBootTest 注释添加到您的测试、 Autowiring 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();
    }
}

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

@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();
}

关于java - 测试 Spring Boot RestTemplate 客户端的 JSON 映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54650873/

相关文章:

java - 如何在同一类的其他对象中设置同一类对象

java - Docker 容器不打印未在 log4j2.xml 中指定的位置的日志

java - fragment 和 fragmentActivity 的 Android 问题

java - 为什么 log4j 消息会产生 UTC 时间戳?

java - ImageView - 显示新图像并在 1 秒后重置 - onClick

Java Scanner 输入困境。自动输入,不允许用户输入

java - 在 Thymeleaf 中使用 DateFormat.SHORT

java - JUnit:NoClassDefFoundError:org/junit/runner/manipulation/Filter

java - JUnit 测试 - 参数化测试 - 'No implicit conversion of type java.lang.Integer to type [Ljava.lang.Integer;'

java - JUnit 类型安全的 assertEquals