mybatis冒烟测试工具


日常中的开发工作,大部分都是增删改查,所以和SQL打交道的时候特别多,我在日常工作中,使用的最多的是mybatis和mysql,用的是spring boot框架,所以在改完代码之后,全量测试下SQL是否正确,就非常重要了。有时候单元测试没来得及写全,所以有一个简单的工具,可以做一下冒烟测试,也是非常有必要的,可以避免低级错误。 所以就萌生了一个想法,通过反射,获取系统中的所有的SQL,挨个执行一遍,简单测试下SQL是否报错。

PS: 如果想要做精细化的测试,还需要自己单独写单元测试。

1、说干就干

思路明确了,先去网上搜索下,有没有别人已经做过了。简单搜了下,确实有人做过,必须要传入dao文件的物理路径,然后解析文件,这明显不是我想要的效果。

  • 通过spring boot拿所有的代理类,没有行的通,失败。

  • 通过反射拿所有的类,需要硬编码所有的dao的名字,失败。

  • 相继失败之后,研究了下mybatis原理,发现所有的代理类,都封装成了MapperFactoryBean,通过ApplicationContext拿所有的这个类,成功。

2、一些挫折

拿到了 MapperFactoryBean之后,却怎么也拿不到MapperProxy,MapperProxy是mybatis的代理类,本来想强制转换的,结果一直报com.sun.proxy.$80Proxy不能转换为MapperProxy,郁闷,必须转换下思路。

3、解决

反射执行方法,是method.invoke(obj,param); obj是不是不需要转换? 我的天,绕弯路了,根本不需要转换得到MapperProxy,直接就解决了,剩下的问题就比较简单了。

  • 拿到dao类,反射得到所有的方法。
  • 解析方法的参数,使用随机工具类,生成测试参数。
  • 对于long类型的id,控制下范围。
  • 对于string类型的,控制下长度,毕竟数据库里的varchar,一般都有最大长度。

4、代码

直接看代码吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Test
public void testAllDao() throws Throwable {

Map<String, MapperFactoryBean> map = SpringContextUtil.getApplicationContext().getBeansOfType(org.mybatis.spring.mapper.MapperFactoryBean.class);
for (Map.Entry<String, MapperFactoryBean> entry : map.entrySet()) {
MapperFactoryBean mapperFactoryBean = entry.getValue();
Class clz2 = mapperFactoryBean.getMapperInterface();
Object object = mapperFactoryBean.getObject();
Method[] methods = clz2.getMethods();
for (Method method : methods) {
Class[] paramClz = method.getParameterTypes();
Object[] param = new Object[paramClz.length];
for (int i = 0; i < paramClz.length; i++) {
param[i] = newInstance(paramClz[i]);
}
try {
method.invoke(object, param);
System.out.println("执行class " + clz2.getName() + " 方法 " + method.getName() + " 成功");
} catch (Exception e) {
System.out.println("执行class " + clz2.getName() + " 方法 " + method.getName() + " 异常");
e.printStackTrace();
}
}

}
System.out.println("执行结束。。。。。。。。。。。。");
}

4、小结

遇到问题不要慌,先网上搜,再看原理,遇到问题,都需要先假设犯了低级错误。