Spring Webflux

Wiremock 入门教程2 - 自定义mock内部逻辑

2020-05-07  本文已影响0人  这个世界是虚拟的

1. 为什么需要自定义mock逻辑

假设我们我们的远端依赖接口, 可以根据不同的入参响应不同的结果, 那么此时写死的mock请求和响应就不适用了, 此时我们便需要自定义mock内部的逻辑处理

2. 使用场景

例如, 我们内部依赖的接口是 POST http://somehost.com/submit/something, 此时按远端处理POST请求Request返回一个 '{name:aaa , ... ...}', 如果我们改变请求体, 那么它将返回其他请求, 这时我们将可以使用wiremock 中的自定义处理逻辑.

3. 代码

3.1. 环境搭建

请查看查看上一篇文章 Wiremock + Spring reactor的简单集成测试

3.2. 代码实现

3.2.1. Controller

没什么特殊的, 就是一个简单的控制器

@PostMapping(path = "/transform")
    public Mono<ResponseEntity<String>> transform(@RequestBody final String requestBody) {
        return dummyService.transform(requestBody)
                .map(res -> {
                    log.info("response from remote server: {}", res);
                    return ResponseEntity.ok(res);
                });
    }

3.2.2. Service

使用webClient发送post请求地址/change/id, 请求远端数据

private static final String TRANSFORM_PATH = "/change/id";

public Mono<String> transform(String bodyValue) {
        log.info("processing bodyValue, {}", bodyValue);
        return webClient.post()
                .uri(TRANSFORM_PATH)
                .bodyValue(bodyValue)
                .retrieve()
                .bodyToMono(String.class);
    }

3.2.3. Stub (定义mock行为)

这里和之前不同的地方是, 我们使用了.withTransformers(DummyResponseTransformer.DUMMY_TRANSFORMER), 这个Transformer 变是我们自定义mock服务器的处理逻辑入口, 我们继续来看这个Transformer张啥样

stubFor(post(urlEqualTo("/change/id")).willReturn(aResponse()
                .withTransformers(DummyResponseTransformer.DUMMY_TRANSFORMER)
                .withTransformerParameter("prefix", "Hello_")));

3.2.4. ResponseTransformer

可以看到, 上一步Stub中的 DummyResponseTransformer.DUMMY_TRANSFORMER 就是这个ResponseTransformer 的一个flag, 当stub注册到这个flag 将使用此Transformer, 也就是使用此逻辑来处理请求, 这个例子中,我们只是简单的拼装了 请求的body和参数作为返回

@Slf4j
public class DummyResponseTransformer extends ResponseTransformer {

    // transformer 标签(name)
    static final String DUMMY_TRANSFORMER = "post_request_to_dummy_transformer";

    @Override
    public Response transform(Request request, Response response, FileSource fileSource, Parameters parameters) {
        String prefix = parameters.getString("prefix");
        log.info("receive request id: {}, and prefix:{}", request.getBodyAsString(), prefix);
        String newId = prefix + request.getBodyAsString();
        return Response.response()
                .headers(new com.github.tomakehurst.wiremock.http.HttpHeaders(HttpHeader.httpHeader(org.springframework.http.HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)))
                .status(202)
                .body("{\"id\":\"" + newId + "\"}")
                .build();
    }

   //标签
    @Override
    public String getName() {
        return DUMMY_TRANSFORMER;
    }

    //Non-global transformations
    @Override
    public boolean applyGlobally() {
        return false;
    }
}

3.2.5. 注入Transformer

为了加载Transformer到Spring, 我们需要定义一个配置, 实现WireMockConfigurationCustomizer接口

@Component
public class DummyWireMockConfigurationCustomizer implements WireMockConfigurationCustomizer {
    @Override
    public void customize(WireMockConfiguration config) {
        config.extensions(DummyResponseTransformer.class);
    }
}

3.3. 测试

@Test
    void testTransformer() {

        stubFor(post(urlEqualTo("/change/id")).willReturn(aResponse()
                .withTransformers(DummyResponseTransformer.DUMMY_TRANSFORMER)
                .withTransformerParameter("prefix", "Hello_")));

        webTestClient
                .post()
                .uri("/test/transform")
                .bodyValue("666")
                .exchange()
                .expectStatus().isEqualTo(HttpStatus.OK)
                .expectBody(String.class)
                .consumeWith(stringEntityExchangeResult -> {
                    String responseBody = stringEntityExchangeResult.getResponseBody();
                    log.info(responseBody);
                    Assertions.assertEquals(responseBody, "{\"id\":\"Hello_666\"}");
                });

    }

4. 完整代码

https://github.com/wallisnow/wiremock_spring_reactor

5. 结语

Wiremock 定制化的mock内部逻辑处理可以方便我们根据外部已知的条件来定义我们的mock服务器, 本例中实现的是response transformer, 它还提供了其他的一些 定制化的Extension, 可以查看官方文档: http://wiremock.org/docs/extending-wiremock/. 但是这里有提供的代码有一个缺点, 就是这个transformer 似乎只能有一个, 那么我们就需要想办法注入多个transformer 来实现多种transform, 后续我们将实现这个需求

上一篇下一篇

猜你喜欢

热点阅读