网易首页 > 网易号 > 正文 申请入驻

IDEA懒人必备插件,自动生成单元测试,太爽了!

0
分享至

今天来介绍一款工具Squaretest,它是一款自动生成单元测试的插件,为什么会用到它?

主要因为最近公司上了代码质量管控的指标,会考评各个项目的单元测试覆盖率,以及sonar扫描出来的各种问题,很多老项目老代码,或者着急交付的项目,单元测试严重缺失,覆盖率只有5%不到。

所以几个小伙伴这几天就在疯狂的堆单元测试,3个人堆了2天才堆到30%,于是我也来上手帮忙写了两个,写到第二个的时候就发现,这个活不应该是人干的,要去看原来的代码,然后根据逻辑写各种Mock,感觉是有迹可循的东西,所以就查了下,发现果然有插件帮我们来干这个事情,那么解下来就来看看。

我使用的是idea,我们先来下载一下插件,File——>Settings——>Plugins,搜索Squaretest,然后install就好了,插件安装完成后需要重启一下

重启之后,菜单栏就多了一项Squaretest,下面我们来讲下怎么用,大家也可以通过看这个菜单的最后一项:Generate Test Methods(Help)来看它的一个演示,但演示不太全,我下面截图给大家看下我怎么用的,以及一些使用心得。

首先我们打开一个类,这个类就是我们即将要作为实验的类,这个类有7个public方法,因为Squaretest生成的单元测试方法都是只能生成public的,当然这也是合理的嘛!毕竟private的肯定被public调用了。

如果我们来手写这个类的,光看都要一会,下面看我操作,打开你的类,光标定位到代码里,右击鼠标选择Generate…

然后你就会看到这里有两个熟悉的图标,第一次的话选择第二个选项,它会让你选择你一下单元测试的模板,因为我已经选择过了,所以我现在演示不回再弹出,但后面我会告诉你怎么更改模板。

选择第二项后就会弹出一个框看下面这里它自动会识别出当前类需要Mock的成员变量,直接点ok

自动会使用类的真实目录层次在test文件夹中创建出来一个单元测试类,类名就是原类名后加Test

我把代码贴出来给大家看看它生成出来的是什么样的,看看吓不吓人,牛逼牛逼,7个单元测试方法,秒秒钟就出来了,各位看官你们自己写要多久能写出来,毕竟时间就是金钱啊!然后我们执行一把试试!

public class CrawlerScreenShotServiceImplTest {

@Mock
private CrawerScreenShotTaskMapper mockCrawerScreenShotTaskMapper;
@Mock
private CrawerScreenShotTaskLogMapper mockCrawerScreenShotTaskLogMapper;

@InjectMocks
private CrawlerScreenShotServiceImpl crawlerScreenShotServiceImplUnderTest;

@Before
public void setUp() {
initMocks(this);
}

@Test
public void testReceiveData() {
// Setup
final CrawlerScreenShotVO vo = new CrawlerScreenShotVO();
vo.setUrl("url");
vo.setPcFlag(false);
vo.setMembergroup("membergroup");
vo.setTaskType(0);
vo.setUrlType(0);

when(mockCrawerScreenShotTaskLogMapper.saveSelective(any(CrawerScreenShotTaskLog.class))).thenReturn(0);
when(mockCrawerScreenShotTaskMapper.saveBatch(Arrays.asList(new CrawlerScreenShotTask(0L, "url", "imageOssUrl", false, false, "memberGroup", 0, 0, "fileName", new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime(), new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime(), false, "skuCode", "state", "operater")))).thenReturn(0);

// Run the test
final Result result = crawlerScreenShotServiceImplUnderTest.receiveData(vo);

// Verify the results
}

@Test
public void testListJobScreenShotTask() {
// Setup

// Configure CrawerScreenShotTaskMapper.listJobScreenShotTask(...).
final CrawlerScreenShotTaskDto crawlerScreenShotTaskDto = new CrawlerScreenShotTaskDto();
crawlerScreenShotTaskDto.setId(0L);
crawlerScreenShotTaskDto.setUrl("url");
crawlerScreenShotTaskDto.setSkuCode("skuCode");
crawlerScreenShotTaskDto.setPcFlag(false);
crawlerScreenShotTaskDto.setMemberGroup("memberGroup");
crawlerScreenShotTaskDto.setUrlType(0);
crawlerScreenShotTaskDto.setFileName("fileName");
crawlerScreenShotTaskDto.setTaskType(0);
crawlerScreenShotTaskDto.setState("state");
final List crawlerScreenShotTaskDtos = Arrays.asList(crawlerScreenShotTaskDto);
when(mockCrawerScreenShotTaskMapper.listJobScreenShotTask(new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime())).thenReturn(crawlerScreenShotTaskDtos);

// Run the test
final List result = crawlerScreenShotServiceImplUnderTest.listJobScreenShotTask();

// Verify the results
}

@Test
public void testQuery() {
// Setup
final NikeScreenShotListRequestVo requestVo = new NikeScreenShotListRequestVo();
requestVo.setUrl("url");
requestVo.setUrlType(0);
requestVo.setStartTime(new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime());
requestVo.setEndTime(new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime());
requestVo.setStatus(0);
requestVo.setPcFlag(0);
requestVo.setPageNum(0);
requestVo.setPageSize(0);

// Configure CrawerScreenShotTaskMapper.query(...).
final PimScreenShotVo pimScreenShotVo = new PimScreenShotVo();
pimScreenShotVo.setId(0L);
pimScreenShotVo.setUrl("url");
pimScreenShotVo.setImageOssUrl("imageOssUrl");
pimScreenShotVo.setStatus(0);
pimScreenShotVo.setPcFlag(false);
pimScreenShotVo.setCreateTime(new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime());
pimScreenShotVo.setUrlType(0);
pimScreenShotVo.setMsg("msg");
final List pimScreenShotVos = Arrays.asList(pimScreenShotVo);
when(mockCrawerScreenShotTaskMapper.query(any(NikeScreenShotListRequestVo.class))).thenReturn(pimScreenShotVos);

// Run the test
final PageInfo result = crawlerScreenShotServiceImplUnderTest.query(requestVo);

// Verify the results
}

@Test
public void testQuerySelectBoxData() {
// Setup

// Configure CrawerScreenShotTaskMapper.query(...).
final PimScreenShotVo pimScreenShotVo = new PimScreenShotVo();
pimScreenShotVo.setId(0L);
pimScreenShotVo.setUrl("url");
pimScreenShotVo.setImageOssUrl("imageOssUrl");
pimScreenShotVo.setStatus(0);
pimScreenShotVo.setPcFlag(false);
pimScreenShotVo.setCreateTime(new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime());
pimScreenShotVo.setUrlType(0);
pimScreenShotVo.setMsg("msg");
final List pimScreenShotVos = Arrays.asList(pimScreenShotVo);
when(mockCrawerScreenShotTaskMapper.query(any(NikeScreenShotListRequestVo.class))).thenReturn(pimScreenShotVos);

// Run the test
final PimScreenShotTaskParamsDto result = crawlerScreenShotServiceImplUnderTest.querySelectBoxData();

// Verify the results
}

@Test
public void testFindExecutionScreenShotTaskCount() {
// Setup
when(mockCrawerScreenShotTaskMapper.findExecutionScreenShotTaskCount()).thenReturn(0);

// Run the test
final Integer result = crawlerScreenShotServiceImplUnderTest.findExecutionScreenShotTaskCount();

// Verify the results
assertEquals(0, result);
}

@Test
public void testFindCrawerScreenshotTaskByCreateTime() {
// Setup
final CrawlerScreenShotTaskSyncDto crawlerScreenShotTaskSyncDto = new CrawlerScreenShotTaskSyncDto();
crawlerScreenShotTaskSyncDto.setId(0L);
crawlerScreenShotTaskSyncDto.setUrl("url");
crawlerScreenShotTaskSyncDto.setSkuCode("skuCode");
crawlerScreenShotTaskSyncDto.setTaskType(0);
crawlerScreenShotTaskSyncDto.setStatus(0);
crawlerScreenShotTaskSyncDto.setLastModifyTime(new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime());
crawlerScreenShotTaskSyncDto.setOperater("operater");
crawlerScreenShotTaskSyncDto.setMsg("msg");
final List expectedResult = Arrays.asList(crawlerScreenShotTaskSyncDto);

// Configure CrawerScreenShotTaskMapper.findCrawerScreenshotTaskByCreateTime(...).
final CrawlerScreenShotTaskSyncDto crawlerScreenShotTaskSyncDto1 = new CrawlerScreenShotTaskSyncDto();
crawlerScreenShotTaskSyncDto1.setId(0L);
crawlerScreenShotTaskSyncDto1.setUrl("url");
crawlerScreenShotTaskSyncDto1.setSkuCode("skuCode");
crawlerScreenShotTaskSyncDto1.setTaskType(0);
crawlerScreenShotTaskSyncDto1.setStatus(0);
crawlerScreenShotTaskSyncDto1.setLastModifyTime(new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime());
crawlerScreenShotTaskSyncDto1.setOperater("operater");
crawlerScreenShotTaskSyncDto1.setMsg("msg");
final List crawlerScreenShotTaskSyncDtos = Arrays.asList(crawlerScreenShotTaskSyncDto1);
when(mockCrawerScreenShotTaskMapper.findCrawerScreenshotTaskByCreateTime(new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime())).thenReturn(crawlerScreenShotTaskSyncDtos);

// Run the test
final List result = crawlerScreenShotServiceImplUnderTest.findCrawerScreenshotTaskByCreateTime(new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime());

// Verify the results
assertEquals(expectedResult, result);
}

@Test
public void testQueryCrawlerDashboard() {
// Setup
when(mockCrawerScreenShotTaskMapper.queryCrawlerDashboard(0, 0, 0, new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime(), new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime())).thenReturn(0);

// Run the test
final Integer result = crawlerScreenShotServiceImplUnderTest.queryCrawlerDashboard(0, 0, 0, new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime(), new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime());

// Verify the results
assertEquals(0, result);
}
}

报错了呢,不要慌,这个断言是为了检查你单元测试跑出来的结果是否符合预期的,如果你不想检查只想完成覆盖率,直接干掉就可以了(手动狗头)。

怎么样!刺不刺激,爽不爽,秒秒钟90多行的代码覆盖率就到了90%以上.

上面说过第一次进来会让你选择单元测试的模板,如果你要切换的话可以在单元测试类中按快捷键,Alt+M,或者通过Squaretest的菜单倒数第二个,下面这个就是按快捷键的效果,我选择的是这个模板,你们也可以借鉴。

OK,以上Squaretest部分就结束了,当然拉也不能高兴的太早,这个类算是比较成功的情况,很多时候还是要你自己小修小改的,毕竟它生成出来的测试数据可能完全匹配不上你的if else数据对吧,但这都很好改啊,这样就从自己分析if else变成了,debug程序了呀,哪里报错,debug过去,看看是不是生成的数据有问题,改个数据,就通过了,反正本人用的是很舒畅的,妥妥的节省70%的工作量。另外,公众 号Java精选,回复java面试,获取在线面试刷题神器。

解决了上面一个问题之后,又发现另一个问题,这个工具VO,DTO,Entity,Command,Model这种实体类来讲,一般这种实体类我们都用lombok的注解get,set,还有constract构造器等注解,但是这个工具只能生成这些实体类的构造器的单元测试,无法生成get set方法的单元测试,所以写了个base方法,实体类继承一下,简单的写两行带就好了,看下面代码:

@SpringBootTest
@RunWith(MockitoJUnitRunner.class)
public abstract class BaseVoEntityTest {
protected abstract T getT();

private void testGetAndSet() throws IllegalAccessException, InstantiationException, IntrospectionException,
InvocationTargetException {
T t = getT();
Class modelClass = t.getClass();
Object obj = modelClass.newInstance();
Field[] fields = modelClass.getDeclaredFields();
for (Field f : fields) {
boolean isStatic = Modifier.isStatic(f.getModifiers());
// 过滤字段
if (f.getName().equals("isSerialVersionUID") || f.getName().equals("serialVersionUID") || isStatic || f.getGenericType().toString().equals("boolean")
|| f.isSynthetic()) {
continue;
}
PropertyDescriptor pd = new PropertyDescriptor(f.getName(), modelClass);
Method get = pd.getReadMethod();
Method set = pd.getWriteMethod();
set.invoke(obj, get.invoke(obj));
}
}

@Test
public void getAndSetTest() throws InvocationTargetException, IntrospectionException,
InstantiationException, IllegalAccessException {
this.testGetAndSet();
}

}

同样的方式我们在实体类上通过Squaretest生成单元测试,然后继承我上面写的那个base类,vo的单元测试代码稍加改动,如下

看run完之后,覆盖率100%,妥妥的,通过这两个解决方案,一天之内我们就把覆盖率搞到了60%以上,不要太刺激,大家可以用用试试哦,当然这个也不是纯为了应付差事写的单元测试,我们后续开发的时候,也可以用这个工具来生成,然后自测自己的代码,这样也是提升工作效率的嘛!

公众号“Java精选”所发表内容注明来源的,版权归原出处所有(无法查证版权的或者未注明出处的均来自网络,系转载,转载的目的在于传递更多信息,版权属于原作者。如有侵权,请联系,笔者会第一时间删除处理!

最近有很多人问,有没有读者交流群!加入方式很简单,公众号Java精选,回复“加群”,即可入群!

(微信小程序):3000+道面试题,包含Java基础、并发、JVM、线程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架构设计等,在线随时刷题!

特别推荐:专注分享最前沿的技术与资讯,为弯道超车做好准备及各种开源项目与高效率软件的公众号,「大咖笔记」,专注挖掘好东西,非常值得大家关注。点击下方公众号卡片关注

文章有帮助的话,点在看,转发吧!

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
被恒大坑苦的几大装修老板,只有他提前醒悟,落袋14.6亿安全离场

被恒大坑苦的几大装修老板,只有他提前醒悟,落袋14.6亿安全离场

校长侃财
2024-12-01 11:06:25
曼联4-0埃弗顿,赛后评分:不是拉什福德第一,而是曼联16号第一

曼联4-0埃弗顿,赛后评分:不是拉什福德第一,而是曼联16号第一

凌空倒钩
2024-12-01 23:23:06
18板+14板+14板!超级内线诞生,你再这样打下去,快船真要后悔了

18板+14板+14板!超级内线诞生,你再这样打下去,快船真要后悔了

巴叔GO聊体育
2024-12-01 16:31:30
当年直播香港回归的4位主持人:2人去世,1人落魄,1人退休......

当年直播香港回归的4位主持人:2人去世,1人落魄,1人退休......

华人星光
2024-12-01 12:24:06
冠军师兄评管晨辰:等你光环散去,过气了,你就会理解吴柳芳

冠军师兄评管晨辰:等你光环散去,过气了,你就会理解吴柳芳

米君文史
2024-11-30 20:13:29
32岁古力娜扎太敢穿,丁字裤外露不遮不掩,大胆自信又率真

32岁古力娜扎太敢穿,丁字裤外露不遮不掩,大胆自信又率真

南城无双
2024-12-02 00:52:34
英国情报六局:若俄罗斯总统普京获胜了,中国将权衡其影响

英国情报六局:若俄罗斯总统普京获胜了,中国将权衡其影响

新时光点滴
2024-12-01 08:32:25
极氪宣布终身质保电池可免费换,网友:这才是良心企业

极氪宣布终身质保电池可免费换,网友:这才是良心企业

笔尖下的人生
2024-12-01 19:20:37
德国大众宣布出售新疆工厂

德国大众宣布出售新疆工厂

EETOP半导体社区
2024-11-29 11:47:45
日本祖先被证实,不是徐福后代,DNA检测让日本人无法接受

日本祖先被证实,不是徐福后代,DNA检测让日本人无法接受

杨哥历史
2024-11-30 09:38:36
杨政和女友近照,年入百万,31岁进CBA,混血女友很漂亮

杨政和女友近照,年入百万,31岁进CBA,混血女友很漂亮

大西体育
2024-12-01 23:35:02
中国彻底崩塌的专业,月薪从1.5万降到3000,大批毕业生无法就业

中国彻底崩塌的专业,月薪从1.5万降到3000,大批毕业生无法就业

教育导向分享
2024-11-30 17:36:11
伟大的10-8!特鲁姆普13年后再夺冠,解锁3大纪录,张安达受益!

伟大的10-8!特鲁姆普13年后再夺冠,解锁3大纪录,张安达受益!

刘姚尧的文字城堡
2024-12-02 06:44:18
新任FBI局长公布,外网炸锅了!他要彻查清理官员,或公布911及肯尼迪遇刺真相

新任FBI局长公布,外网炸锅了!他要彻查清理官员,或公布911及肯尼迪遇刺真相

西游日记
2024-12-01 14:50:15
不声不响就逆转!灰熊多点开花&11人有得分入账 7人得分上双!

不声不响就逆转!灰熊多点开花&11人有得分入账 7人得分上双!

直播吧
2024-12-02 07:14:18
99年朱总理访美,被问中国给克林顿30万献金,总理:怎么才30万?

99年朱总理访美,被问中国给克林顿30万献金,总理:怎么才30万?

WarOH协虎
2024-12-01 22:10:02
知名影帝自曝:已交代好后事

知名影帝自曝:已交代好后事

环球网资讯
2024-11-29 13:04:05
12月2日体育直播有变:CCTV5、CCTV5+节目单,坐等孙颖莎出战

12月2日体育直播有变:CCTV5、CCTV5+节目单,坐等孙颖莎出战

阿柒体讯
2024-12-02 00:24:46
雨雪明天到!要穿厚外套!

雨雪明天到!要穿厚外套!

鲁中晨报
2024-12-01 21:24:10
巴黎圣母院“重生”!召集全法国能工巧匠努力五年,终于重开!

巴黎圣母院“重生”!召集全法国能工巧匠努力五年,终于重开!

英国那些事儿
2024-11-30 23:19:17
2024-12-02 08:24:49
Java精选
Java精选
一场永远也演不完的戏
1601文章数 3853关注度
往期回顾 全部

科技要闻

我国首个商业航天发射场首发成功

头条要闻

中企参加CES遭大规模拒签 环球:美国务院需尽快回应

头条要闻

中企参加CES遭大规模拒签 环球:美国务院需尽快回应

体育要闻

勇士四连败,到底是谁的错?

娱乐要闻

黄晓明姥姥去世,祖孙俩手牵手好温馨

财经要闻

400人获刑!诈骗集团后台控制"股票"涨跌

汽车要闻

科技是中国豪车梦的支点 腾势Z9走心试驾体验

态度原创

本地
时尚
亲子
数码
军事航空

本地新闻

云游中国|来伦布夏果感受充满Passion的人生

今冬流行“不露腿”穿搭!舒适还保暖,巨洋气!

亲子要闻

某些维生素或致孕妇诞下自闭症婴儿

数码要闻

联想推出异能者 SG10 Pro 智能音乐眼镜,199 元

军事要闻

泽连斯基开出停火条件 俄方回应

无障碍浏览 进入关怀版