【从0到1开发一个网关】网关Mock功能的实现

341 阅读2分钟

代码讲解链接

项目开源代码-点个star领取完整4w字开发文档

什么是Mock?

Mock(模拟)是一种测试技术,用于创建虚拟对象来模拟真实对象的行为。Mock对象模拟了真实对象的行为,但是不依赖于真实对象的实现细节。它们可以在测试中替代真实对象,以便进行独立的单元测试。

需要使用Mock的原因包括以下几点:

依赖项不可用:在进行单元测试时,某些依赖项可能无法访问或不可用,例如数据库、网络服务等。使用Mock对象可以模拟这些依赖项的行为,使测试能够独立运行。

控制测试环境:使用Mock对象可以控制测试环境中的各种情况和条件,例如模拟错误、异常、超时等,以确保代码在各种情况下的正确性和稳定性。

提高测试性能:某些依赖项可能是耗时的操作,例如数据库查询、网络请求等。使用Mock对象可以避免这些耗时操作,提高测试的执行速度。

隔离测试:使用Mock对象可以将被测试对象与其依赖项进行隔离,确保测试的独立性。这样可以更容易地定位和调试问题,同时也提高了测试的可维护性。

Mock对象在单元测试中扮演了替代真实对象的角色,使得测试更加独立、可控和高效。通过使用Mock对象,开发人员可以更好地测试代码的各种情况和边界条件,提高软件的质量和可靠性。

如何实现Mock

这里还是一样,我们增加一个过滤器,当当前请求路径需要走mock的时候,这个过滤器才会生效。 并且由于我们走了mock,那么实际上这些请求的返回数据都是我们自己定好的,因此我们可以直接返回,而不需要继续走其他的过滤器流程。

@Slf4j
@FilterAspect(id=MOCK_FILTER_ID,
        name = MOCK_FILTER_NAME,
        order = MOCK_FILTER_ORDER)
public class MockFilter implements Filter {
    @Override
    public void doFilter(GatewayContext ctx) throws Exception {
        //如果没有配置mock 直接返回
        Rule.FilterConfig config = ctx.getRule().getFilterConfig(MOCK_FILTER_ID);
        if (config == null) {
            return;
        }
        //解析
        Map<String, String> map = JSONUtil.parse(config.getConfig(), Map.class);
        String value = map.get(ctx.getRequest().getMethod().name() + " " + ctx.getRequest().getPath());
        //不为空说明命中了mock规则
        if (value != null) {
            ctx.setResponse(GatewayResponse.buildGatewayResponse(value));
            ctx.written();
            //数据写回
            ResponseHelper.writeResponse(ctx);
            log.info("mock {} {} {}", ctx.getRequest().getMethod(), ctx.getRequest().getPath(), value);
            ctx.terminated();
        }
    }
}

所以这里我在末尾添加了一个terminated方法来中断这个方法。 在这里插入图片描述 最后,在网关中为这个路径添加对应的mock配置

 				 {
                    "id":"mock_filter",
                    "config":{
                        "GET /http-server/ping": "mock"
                    }
                }

在这里插入图片描述