本地開發需要依賴別人的服務時候,如果不想也把依賴服務啟動起來,可以對自己項目中的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開源項目feign中feign-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();
使用說明
支持的返回值類型
- 范型,比如rpc常用的封裝的返回類型 Response
, Response的定義如下
@Data
public class Response<T> {
/**
* 響應碼
*/
private int code;
/**
* 響應描述
*/
private String msg;
/**
* 響應數據
*/
private T data;
}
- 自定義類
@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