feign调用mock
注入feign调用的拦截器,自定义InvocationHandlerFactory,重写代理类的实现。
java
@Bean
public Feign.Builder feignBuilder() {
return Feign.builder().invocationHandlerFactory((target, dispatch) -> new FeignResultInvocationHandler(target, dispatch));
}
java
public class FeignResultInvocationHandler implements InvocationHandler {
public static final Logger logger = LoggerFactory.getLogger(FeignResultInvocationHandler.class);
private final Target target;
private final Map<Method, InvocationHandlerFactory.MethodHandler> dispatch;
public FeignResultInvocationHandler(Target target, Map<Method, InvocationHandlerFactory.MethodHandler> dispatch) {
this.target = checkNotNull(target, "target");
this.dispatch = checkNotNull(dispatch, "dispatch for %s", target);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("equals".equals(method.getName())) {
try {
Object otherHandler =
args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null;
return equals(otherHandler);
} catch (IllegalArgumentException e) {
return false;
}
} else if ("hashCode".equals(method.getName())) {
return hashCode();
} else if ("toString".equals(method.getName())) {
return toString();
}
// 以上eauals、hashCode等方法需要复制过来,要不然会因方法名问题影响文件的读取
String methodName = getMethodName(method);
Type returnType = method.getGenericReturnType();
Function<String, Object> mockFunction = filePath -> getMockReturnType(filePath, returnType);
Function remoteFunction = s -> {
try {
return dispatch.get(method).invoke(args);
} catch (Throwable e) {
logger.error("methodName={} feign remote error", methodName, e);
throw new RuntimeException(e);
}
};
Object result = TestFileHelper.getResult(methodName, mockFunction, remoteFunction);
return result;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof FeignResultInvocationHandler) {
FeignResultInvocationHandler other = (FeignResultInvocationHandler) obj;
return target.equals(other.target);
}
return false;
}
@Override
public int hashCode() {
return target.hashCode();
}
@Override
public String toString() {
return target.toString();
}
private String getMethodName(Method method) {
String className = method.getDeclaringClass().getName();
return className.substring(className.lastIndexOf(".") + 1) + "_" + method.getName();
}
public Object getMockReturnType(String filePath, Type type) {
String result = TestFileHelper.readFile(filePath);
if (type == null) {
return result;
}
try {
// com.google.gson.Gson就是比fastjson好用,这里按类型转换使用Gson非常简单
Object obj = new Gson().fromJson(result, type);
return obj;
}catch (Exception e){
logger.error("getMockReturnType error", e);
e.printStackTrace();
}
return result;
}
}