背景
在生产上线时,可能遇到有一些case不好立即验证;
- 例如用户必须是xx用户(新用户,流失用户…)才能领到某些活动券,而这样的用户账号不好获取;
- 例如想让测试用户看到不同的页面效果;
所以希望在调用一些方法接口的时候针对指定入参可以返回指定的返回结果。
这些方法可以是调用上游的dubbo方法,也可以是内部自己的本地方法等。
方案设计
入参出参分析
首先来看方法的参数和返回结果的类型,以及入参和出参组装分类;
入参出参数据类型分类
- 基本类型或者包装类型:int, double, Integer,String,Boolean…
- 集合类型:List,Map<K, V>…
- 复杂类型:xxxRequest,xxxResponse
入参出参组装分类
入参:
-
无入参
public int fun();
-
一个入参(可能是三种类型的其中一种)
-
public int fun(String s);
-
public int fun(List list);
-
public int fun(xxxRequest request);
-
-
多个入参(可能是三种类型都有)
- public int fun(String s, List list, xxxRequest request);
出参:
-
一个出参(可能是三种类型的其中一种)
-
public Integer fun();
-
public List fun();
-
public xxxResponse fun();
-
-
无出参(不考虑)
mock配置方式
针对上面对方法入参和出参的分析,可以确定我们需要实现mock的场景和配置方式。
入参:match配置内容则返回mock结果
-
方法没有入参,无需配置对比;
-
方法入参类型为基本类型或集合类型(Integer,List);序列化后整体做对比
-
方法入参类型为复杂类型(xxxRequest);可选取部分字段对比
需要注意List也需要序列化后整体做对比
出参:
-
想要构造整个出参的结果;
-
想要从真实调用中修改结果的某几个字段的值;
其中有些字段嵌套的比较深,可利用"a.b.c"的配置方式来修改,可参考下文的配置;
mock流程
从流程上可以看出,为了不影响到接口调用,流程中做了严格的校验处理,一旦报错或者配置信息有误都要真实调用并返回结果。
代码实现
完整代码见github:github.com/XDcherish/j…
1.引入切面与注解
引入切面:
@Bean
public MethodMockAspect methodMockAspect() {
return new MethodMockAspect();
}
切面的扫描范围是添加了@MethodMock的类,这样类中的方法在调用过程中会被切面拦截 。
@MethodMock
public class TestMockClass {
public Boolean testSimpleWithoutInput() {
System.out.println("真实执行啦:");
return true;
}
}
2.增加mock配置
可参考com.xh.utils.mock.dto.MethodMockDTO中的注释进行配置,各字段有详细解释;
mockRequestDTOsList和mockResponseDTOS 都是List表示支持同一个方法的多组入参和出参匹配。
例如下面的配置:
{
"com.xh.utils.mock.test.TestMockClass#testSimpleWithoutInput": { //简单无入参的配置
"openMock": true, //是否开启配置
"mockResponseDTOS": [ //只需要配置response即可,虽然是数组,但只能配置一个
{
"mockType