美文网首页Spring Webflux
Wiremock 入门教程2 - 自定义mock内部逻辑

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

作者: 这个世界是虚拟的 | 来源:发表于2020-05-07 23:18 被阅读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, 后续我们将实现这个需求

    相关文章

      网友评论

        本文标题:Wiremock 入门教程2 - 自定义mock内部逻辑

        本文链接:https://www.haomeiwen.com/subject/xdrwghtx.html