Spring的WebClient通过MockServer挂在bodyToMono(Pojo)上

时间:2018-11-16 12:58:24

标签: java spring okhttp3 spring-webflux

我想模拟一个外部API,这是我在服务中调用的。因此,我想使用okhttp3中的MockWebServer。我的问题是,如果我想以字符串形式检索主体,则对bodyToMono的调用可以正常工作,但是在将其作为数据类检索时却无法正常工作。我尝试使用以下代码片段进行精简:

public class MockWebClientTest {

    private MockWebServer server;

    @BeforeEach
    public void setUp() throws IOException {
        server = new MockWebServer();
        server.start(9876);
    }

    @AfterEach
    public void tearDown() throws IOException {
        server.shutdown();
    }

    @Test
    public void stringWorks() throws JsonProcessingException {
        createMockedTokenCall();

        Mono<String> response = WebClient.create(this.server.url("/").toString())
            .get()
            .uri("/")
            .retrieve()
            .bodyToMono(String.class);

        System.out.println(response.block());
    }

    @Test
    public void classDoesNotWork() {
        createMockedTokenCall();

        Mono<AuthToken> response = WebClient.create(this.server.url("/").toString())
            .get()
            .uri("/")
            .retrieve()
            .bodyToMono(AuthToken.class);

        System.out.println(response.block());
    }

    private void createMockedTokenCall() {
        server.enqueue(new MockResponse().setBody("{\"accessToken\":\"BARBAR\",\"refreshToken\":\"FOOFOO\"}"));
    }
}

class AuthToken {
    private String accessToken;
    private String refreshToken;

    //constructor
}

第一个测试(stringWorks)运行正常,并返回正确的json表示形式。但是,第二个测试(classDoesNotWork)永远挂在bodyToMono调用上。

我的猜测是,它与okttp3库没有直接关系,因为我使用Wiremock遇到相同的错误。但是,当针对真实的API端点时,相同的代码也可以工作。不幸的是,我找不到其他使用WebClient来测试我的呼叫的方法,因为Spring目前没有直接的模拟支持(请参见SPR-15286)。

我真的很乐意为您提供帮助!预先感谢!

一般性说明:这基本上是https://github.com/spring-projects/spring-framework/blob/master/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java中测试用例shouldReceiveJsonAsPojo的副本

1 个答案:

答案 0 :(得分:0)

好吧,在查看了链接的测试并进行了一些比较之后,我找到了解决方案(或者可以说是我的错误):我忘记了正确的Content-Type标头。因此它可以通过以下方式工作:

private void createMockedTokenCall() {
    server.enqueue(new MockResponse().setHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE).setBody("{\"accessToken\":\"BARBAR\",\"refreshToken\":\"FOOFOO\"}"));
}

除了我犯了一个错误外,我真的认为这不应导致应用程序无限死机...