zoukankan      html  css  js  c++  java
  • 基于Spring Cloud Feign的Mock工具

    本地开发需要依赖别人的服务时候,如果不想也把依赖服务启动起来,可以对自己项目中的feign client进行mock,这个工具支持直接在feign client接口上对返回值进行mock,不需要在fallback中编写负责冗长的代码来实现。

    如何构建

    git clone git@github.com:markytsai/feign-hystrix-mocker.git
    mvn clean install -DskipTest=true

    如果你知道maven或者gradle的依赖原则,则根据规则引用生成的jar包
    如果不清楚,可以直接在spring-cloud-starter-openfeign排除内部引用的feign-hystrix版本,然后自己生成的jar包

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
        <version>2.0.1.RELEASE</version>
        <exclusions>
            <exclusion>
                <groupId>io.github.openfeign</groupId>
                <artifactId>feign-hystrix</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    

    原理

    Feign mocker在feign开源项目feignfeign-hystrix模块功能的基础上,对fallback进行了增强,即对FallbackFactory.Default进行封装,当项目启动构建初始化FallbackFactory时候,会根据feign client是否定义@Mock选择是否使用EnhancedFallbackFactory,以替换FallbackFactory默认的实现FallbackFactory.Default. 如远程调用失败则会进行返回值mock;如果调用成功,则不会进入任何一个FallbackFactory.

    使用方法

    只需要在远程调用接口上使用@Mock注解,@Mapping注解配置类中字段的值。type是类型,name是在type类型中的字段,值是value。value格式不匹配会抛出异常,这里需要用户保证正确性,代码不做判断。

    @Mock(mappings = {
            @Mapping(type = Response.class, name = "code", value = "200")
    })
    @GetMapping("/getPeople")
    Response<People> getPeople();
    
    @Mock(mappings = {
            @Mapping(type = Response.class, name = "code", value = "200"),
            @Mapping(type = People.class, name = "name", value = "mock"),
            @Mapping(type = People.class, name = "age", value = "24"),
            @Mapping(type = Address.class, name = "district", value = "hangzhou"),
            @Mapping(type = Address.class, name = "code", value = "0571"),
    })
    @GetMapping("/getPeopleEx")
    Response<People> getPeopleEx();
    

    使用说明

    支持的返回值类型

    1. 范型,比如rpc常用的封装的返回类型 Response, Response的定义如下
    @Data
    public class Response<T> {
    
        /**
         * 响应码
         */
        private int code;
    
        /**
         * 响应描述
         */
        private String msg;
    
        /**
         * 响应数据
         */
        private T data;
    }
    
    1. 自定义类
    @Data
    public class People {
        private String name;
        private Integer age;
        private List<Order> orderList;
        public People() {
        }
        public People(String name, Integer age) {
            this.name = name;
            this.age = age;
        }
    }
    

    说明:这里的T不支持java原生类,如Integer, Double等,必须为自定义类

    /**
     * T: 不支持 Java包装类型的类,导致返回的data并不是mock的200,而是默认值9
     *
     * @return
     */
    @Mock(mappings = {
            @Mapping(type = Response.class, name = "code", value = "200"),
            @Mapping(type = Integer.class, name = "data", value = "200")
    })
    @GetMapping("/getPeopleEx")
    Response<Integer> getInteger();
    

    返回验证

    {
        "code": 200,
        "msg": "success",
        "data": [
            {
                "code": 200,
                "msg": "mockString",
                "data": {
                    "name": "mock",
                    "age": 24,
                    "orderList": [
                        {
                            "orderId": 9,
                            "orderName": "mockString",
                            "addressList": [
                                {
                                    "district": "hangzhou",
                                    "code": "0571"
                                },
                                {
                                    "district": "hangzhou",
                                    "code": "0571"
                                }
                            ]
                        },
                        {
                            "orderId": 9,
                            "orderName": "mockString",
                            "addressList": [
                                {
                                    "district": "hangzhou",
                                    "code": "0571"
                                },
                                {
                                    "district": "hangzhou",
                                    "code": "0571"
                                }
                            ]
                        }
                    ]
                }
            },
            {
                "code": 200,
                "msg": "mockString",
                "data": 9
            }
        ]
    }{
      "code": 200,
      "msg": "mockString",
      "data": {
        "list": [
          {
            "id": 9,
            "workNo": "mockString"
          }
        ]
      }
    }
    

    暂不支持返回值中存在循环依赖。如果有,会抛出异常。

    源码仓库:https://github.com/markytsai/feign-hystrix-mocker
    详细使用方法参考这个仓库:https://github.com/markytsai/mock-test

  • 相关阅读:
    由保存当前用户引发的springboot的测试方式postman/restlet还是swagger2
    VS集成opencv编译C++项目遇到的问题
    利用StringUtils可以避免空指针问题
    springboot集成Guava缓存
    Oracle 课程四之索引
    Oracle 课程三之表设计
    Oracle 课程二之Oracle数据库逻辑结构
    Oracle 课程一之Oracle体系结构
    Oracle权限一览表
    Informatica元数据库解析
  • 原文地址:https://www.cnblogs.com/markytsai/p/15346662.html
Copyright © 2011-2022 走看看