SpringBootTest测试框架二

sql的mock

注入sql的拦截器,对查询语句拦截,按规则访问本地路径的文件,实现mock功能。


@Intercepts(value = {
        @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class,
                RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),
        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class,
                RowBounds.class, ResultHandler.class})})
public class SqlResultInterceptor implements Interceptor {

    private static Logger logger = LoggerFactory.getLogger(SqlResultInterceptor.class);

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        MappedStatement mappedStatement = getInvokeSqlStatement(invocation);

        String methodName = getStatementName(mappedStatement);

        Class<?> returnType = invocation.getMethod().getReturnType();

        Class<?> type = getResultType(mappedStatement);

        System.out.println("sql method name is : " + methodName + " , return type is : " + returnType + " , result type is : " + type);


        Function<String, Object> mockFunction = filePath -> getMockResult(filePath, type, returnType);

        Function remoteFunction = s -> {
            try {
                return invocation.proceed();
            } catch (Throwable e) {
                logger.error("methodName={} sql remote error", methodName, e);
                throw new RuntimeException(e);
            }
        };

        Object result = TestFileHelper.getResult(methodName, mockFunction, remoteFunction);

        return result;
    }

    private Object getMockResult(String filePath, Class<?> type, Class<?> returnType) {
        String result = TestFileHelper.readFile(filePath);
        if (type == null && returnType != null) {
            return JSONObject.parseObject(result, returnType);
        }
        Object object = JSONObject.parseArray(result, type);
        return object;
    }
    private Class<?> getResultType(MappedStatement mappedStatement) {
        if (CollectionUtils.isNotEmpty(mappedStatement.getResultMaps())) {
            Class<?> type = mappedStatement.getResultMaps().get(0).getType();
            return type;
        }

        return null;
    }

    private String getStatementName(MappedStatement mappedStatement) {
        String statementId = mappedStatement.getId();
        int indexOf = statementId.lastIndexOf(".");
        String name = statementId.substring(statementId.lastIndexOf(".", indexOf - 1) + 1);
        return name.replace(".", "_");
    }


    private MappedStatement getInvokeSqlStatement(Invocation invocation) throws Exception {
        Object target = invocation.getTarget();

        if (target instanceof Executor) {
            Object[] args = invocation.getArgs();
            MappedStatement ms = (MappedStatement) args[0];
            return ms;
        }

        DefaultResultSetHandler statementHandler = (DefaultResultSetHandler) target;

        try {
            Field feild = statementHandler.getClass().getDeclaredField("mappedStatement");
            feild.setAccessible(true);
            MappedStatement mappedStatement = (MappedStatement) feild.get(statementHandler);
            return mappedStatement;
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }


}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值