你还在为写大量单元测试而烦恼吗,你还在苦苦的构建包装类的值吗?这里有一款mock单元测试代码自动生成的Maven插件,解决开发人员消耗大量时间在单元测试的问题,全面优化开发人员的测试效率和测试时间。
经过本人的亲自使用,外加我在团队的内部"推(qiang)广(tui)"使用,从统计来看,可以减少使用mock测试的小伙伴,至少30-50%的时间。没减少你的测试时间,请拿刀背砍我。
注意,本插件目前无法完成所有的mock测试,让你不用修改一行代码,暂时需要在agt生成mock测试代码的基础上再进行一点修改,例如分支覆盖,断言使用。
本插件的目标是:实现让开发人员不再写一行mock测试代码,agt帮你全部实现
愿景是:减少开发人员的测试负担,专注业务开发与迭代
简称:AGT
项目地址: https://github.com/chenhaoxiang/auto-generate-test-maven-plugin
<plugin>
<groupId>com.uifuture.maven.plugins</groupId>
<artifactId>auto-generate-test-maven-plugin</artifactId>
<version>1.0.0</version>
<configuration>
<testPackageName>com.jiaxuan.heaven.book.service.impl</testPackageName>
</configuration>
</plugin>
(建议使用最新版本):目前最新版本1.1.3
(后续版本如无说明,groupId与artifactId不会再进行更换)
最简单配置:
<plugin>
<groupId>com.uifuture.maven.plugins</groupId>
<artifactId>agt-maven-plugin</artifactId>
<version>(版本号)</version>
<configuration>
<testPackageName>(待测试类的包名,v1.1.3+支持配置多个,英文分号进行隔开)</testPackageName>
</configuration>
</plugin>
(使用最简单的配置,即可使用,感觉后面说明过多的不用往下看)
示例:
<plugin>
<groupId>com.uifuture.maven.plugins</groupId>
<artifactId>agt-maven-plugin</artifactId>
<version>1.1.0</version>
<configuration>
<testPackageName>com.jiaxuan.heaven.book.service.impl</testPackageName>
</configuration>
<dependencies>
<!-- 引入包,框架可以利用反射找到类,其他项目中的依赖请按照需要进行引入,本配置仅为示例 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
</dependencies>
</plugin>
在引入插件的项目模块下运行maven插件的agt:init命令
mvn agt:init
(v1.1.3+起不再需要先运行agt:init命令,直接运行agt:test即可下载模板文件&生成测试类) agt:init仅仅作为单独下载模板的命令,agt:test包含了agt:init的所有功能
相关配置:
<configPath></configPath>
填写路径,相对路径为当前运行项目的根路径。(默认下载路径:/src/main/resources/test/template)
运行插件的init命令,即可将配置文件下载到对应的路径。
可设置配置文件的文件名,通过<configFileName>magt.ftl</configFileName>
设置配置文件的文件名称。(默认文件名称为magt.ftl)
自动测试代码生成插件
插件生成的mock测试类方法依赖powermock&mockito,建议引入如下依赖(不依赖对于agt插件的运行没有影响)
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.7.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>1.7.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.8.47</version>
<scope>test</scope>
</dependency>
在引入插件的项目名模块下,运行插件的agt:test命令即可在对应的test路径下生成测试用例。
mvn agt:test
<testPackageName>
:必填)配置需要生成单元测试用例的包名,不要填写接口所在包名,需要实现类所在包名,会遍历包下以及子包下所有类和类的方法(v1.1.2支持配置多个包名,英文分号隔开不同的包名) <configPath>
:下载配置文件的路径
<author>
:作者名称
<configFileName>
:下载下来的配置文件的名称
<isGetChildPackage>
:配置testPackageName的包是否递归获取子包下的类(默认true)
<isMockThisOtherMethod>
:配置是否mock掉父类以及自身测试类非测试的方法(默认true),父类/本类方法调用需要使用this进行调用,目前版本无法支持mock
<isSetBasicTypesRandomValue>
:配置是否设置基础类型的值随机生成(默认false)
<setStringRandomRange>
:配置字符串随机值的位数(例如:"10",表示10位随机字母/数字字符)
<setIntRandomRange>
:配置int/Integer类型随机值的范围(例如:"0,1000",表示[0,1000)范围的int数值,配置固定的值可配置为"0",则int值固定为0 )
<setLongRandomRange>
:配置long/Long类型随机值的范围(配置规则与setIntRandomRange类似)
<setBooleanRandomRange>
:配置boolean/Boolean类型随机值的范围(例如:配置为"true"/"false"表示为固定的值,其他任意值表示true和false随机)
<childPackage>
:已更名为 <isGetChildPackage>
<mockPackage>
: <skipPackages>
:<otherProjectName>
:待测试类有依赖第三方Jar包的,需要进行引入插件的依赖,否则agt无法解析到依赖的类信息
配置位置如下所示:
<plugin>
<!-- ... -->
<configuration>
<!-- ... -->
</configuration>
<dependencies>
<!-- 引入包,框架可以利用反射找到类的所有信息 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- ... -->
</dependencies>
</plugin>
分支:version/1.0.0
依赖:
<groupId>com.uifuture.maven.plugins</groupId>
<artifactId>auto-generate-test-maven-plugin</artifactId>
<version>1.0.0</version>
<childPackage>
配置属性修改为<isGetChildPackage>
<testPackageName>
支持配置多个包,多个包使用英文分号";"隔开
配置mock静态方法: 默认使用@RunWith(MockitoJUnitRunner.class),如果配置了mock静态方法,将使用@RunWith(PowerMockRunner.class)。
使用PowerMockRunner与MockitoJUnitRunner类,都无法支持父类中的属性(service的实现类中又同时注入了该类)自动注入的mock(例如mybatis中service层的泛型父类中的泛型baseMapper)。这是由于Mock类会将这两个类作为不同的实例来进行处理,只会mock掉你注入service实现类的基类,而无法注入service实现类的父类中的mapper。
例如:
service实现类
public class WorkFlowServiceImpl extends ServiceImpl<WorkFlowMapper, WorkFlowEntity> implements IWorkFlowService {
@Autowired
private WorkFlowMapper workFlowMapper;
//...
}
父类ServiceImpl:
public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
@Autowired
protected M baseMapper;
//...
}
在WorkFlowServiceImpl中使用时:
baseMapper.deleteById("1");
在mock测试类中:
@RunWith(PowerMockRunner.class)
@PowerMockIgnore("javax.management.*")
@PrepareForTest({BeanConvertUtil.class, FieldBaseDto.class})
public class WorkFlowServiceImplTest {
@InjectMocks
private WorkFlowServiceImpl workFlowServiceImpl;
@Mock
private WorkFlowMapper workFlowMapper;
//...
}
无法进行mock掉baseMapper实例,这是由于baseMapper与workFlowMapper并不是同一个实例!这里仅仅只能mock掉workFlowMapper。
目前可以在service层的实现类中将baseMapper再次注入,则使用PowerMockRunner.class也可以进行mock
service层的实现类不推荐使用泛型基类service父类进行调用泛型mapper操作数据库层!可以选择注入Mapper再进行调用。
199个测试方法,一共覆盖309个被测试方法,使用magt生成后,仅仅只使用了3个多小时进行mock优化(仅仅优化了运行报错的方法,没有进行完善分支测试)。
按照我以前的经验,如果全部由自己写,一切顺利的情况下,199个方法的mock测试,至少要多出几倍的时间。
(此测试项目为使用mybatis-plus的项目,service层的实现类非常多的方法直接使用了父类方法,导致mock很麻烦,耽搁了一些时间,其他项目相对而言会节省更多时间)
目前1.0.0版本不支持分支的覆盖,导致覆盖率不高,将在1.2.0版本后推出分支的多方法mock。大大提高分支覆盖率。
有任何问题/建议欢迎提Issues
20190703拉了个团队小伙伴一块开发,项目从1.1.3版本开始,进入团队内部开发阶段。感谢您的使用。后期更新,本项目会进行同步更新/提醒。
建议您可以先star本项目