基於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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM