SpringBootTest测试框架三

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;
    }


}
相关推荐
NE_STOP8 分钟前
shiro_实现分布式会话SessionManager、限制密码重试次数和并发登录控制
java
Seven9711 分钟前
剑指offer-63、数据流中的中位数
java
毕设源码-钟学长13 分钟前
【开题答辩全过程】以 基于Spring Boot的社区养老服务管理系统的设计与实现为例,包含答辩的问题和答案
java·spring boot·后端
mjhcsp38 分钟前
C++ Manacher 算法:原理、实现与应用全解析
java·c++·算法·manacher 算法
Coder_Boy_38 分钟前
基于SpringAI的在线考试系统-企业级软件研发工程应用规范案例
java·运维·spring boot·软件工程·devops
indexsunny40 分钟前
互联网大厂Java面试实战:微服务、Spring Boot与Kafka在电商场景中的应用
java·spring boot·微服务·面试·kafka·电商
SUDO-11 小时前
Spring Boot + Vue 2 的企业级 SaaS 多租户招聘管理系统
java·spring boot·求职招聘·sass
sheji34161 小时前
【开题答辩全过程】以 基于spring boot的停车管理系统为例,包含答辩的问题和答案
java·spring boot·后端
重生之后端学习1 小时前
21. 合并两个有序链表
java·算法·leetcode·链表·职场和发展
南屿欣风1 小时前
Sentinel 熔断规则 - 异常比例(order & product 示例)笔记
java·开发语言