项目开发过程中,不少公司都要求写单元测试的代码,可以提高代码的质量,并且可以减少出现BUG的概率。

对于中小型公司来说,对单元测试不做硬性要求,不写最好。因为还是需要一定的工作量,在保证代码质量和性能

的前提下,再去考虑单元测试比较合适。有更好,没有也不影响项目的开发进度。自己所在的项目组对于单元测试

有要求,并且要求被测试代码的覆盖率达到20%及以上,每次发布版本的时候,变更覆盖率需要达标才能够发版。

每次写完代码后,基本都会被要求写单元测试的代码,或者是后期补单元测试的代码,总之都得写。

下面就聊聊自己在项目中是如何写单元测试的,使用的框架是Mockito框架,maven的依赖为,

<dependency>

<groupId>org.mockito</groupId>

<artifactId>mockito-core</artifactId>

<version>1.10.19</version>

<scope>test</scope>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

</dependency>

安装Squaretest插件.

选择需要进行单元测试的service实现类.

可以根据需要选择对应的JUnit版本

自己使用的配置为

生成的测试代码示例.

package applets.nature.service.impl;

import applets.nature.entiry.GiftExchangeEntiry;

import applets.nature.entiry.GiftInfo;

import applets.nature.mapper.GiftInfoMapper;

import applets.user.entiry.UserInfo;

import applets.user.service.UserService;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.mockito.InjectMocks;

import org.mockito.Mock;

import org.mockito.runners.MockitoJUnitRunner;

import java.util.Arrays;

import java.util.Collections;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

import static org.assertj.core.api.Assertions.assertThatThrownBy;

import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)

public class GiftHandlerServiceImplTest {

@Mock

private GiftInfoMapper mockGiftInfoMapper;

@Mock

private UserService mockUserService;

@InjectMocks

private GiftHandlerServiceImpl giftHandlerServiceImplUnderTest;

@Test

public void testSelectGiftList() throws Exception {

// Setup

final GiftInfo giftInfo = new GiftInfo();

giftInfo.setGiftId("giftId");

giftInfo.setGiftType("giftType");

giftInfo.setGiftTitle("giftTitle");

giftInfo.setGiftDescription("giftDescription");

giftInfo.setGiftFilePath("giftFilePath");

giftInfo.setNeedLevel(0);

giftInfo.setCreateTime("createTime");

giftInfo.setCreateUser("createUser");

giftInfo.setIsInvalid(0);

giftInfo.setStatus(0);

final List<GiftInfo> expectedResult = Arrays.asList(giftInfo);

// Configure GiftInfoMapper.selectGiftList(...).

final GiftInfo giftInfo1 = new GiftInfo();

giftInfo1.setGiftId("giftId");

giftInfo1.setGiftType("giftType");

giftInfo1.setGiftTitle("giftTitle");

giftInfo1.setGiftDescription("giftDescription");

giftInfo1.setGiftFilePath("giftFilePath");

giftInfo1.setNeedLevel(0);

giftInfo1.setCreateTime("createTime");

giftInfo1.setCreateUser("createUser");

giftInfo1.setIsInvalid(0);

giftInfo1.setStatus(0);

final List<GiftInfo> giftInfos = Arrays.asList(giftInfo1);

when(mockGiftInfoMapper.selectGiftList()).thenReturn(giftInfos);

// Configure UserService.selectUserByOpenid(...).

final UserInfo userInfo = new UserInfo();

userInfo.setUserId("userId");

userInfo.setUserName("userName");

userInfo.setNickName("nickName");

userInfo.setOpenid("openid");

userInfo.setUserPhone("userPhone");

userInfo.setAvatarUrl("avatarUrl");

userInfo.setGender(0);

userInfo.setCreateTime("createTime");

userInfo.setRegistrationCode("registrationCode");

userInfo.setUpdateTime("updateTime");

when(mockUserService.selectUserByOpenid("openid")).thenReturn(userInfo);

when(mockGiftInfoMapper.selectUserExchange("openid")).thenReturn(Arrays.asList(0));

// Run the test

final List<GiftInfo> result = giftHandlerServiceImplUnderTest.selectGiftList("openid");

// Verify the results

assertThat(result).isEqualTo(expectedResult);

}

@Test

public void testSelectGiftList_GiftInfoMapperSelectGiftListReturnsNoItems() throws Exception {

// Setup

when(mockGiftInfoMapper.selectGiftList()).thenReturn(Collections.emptyList());

// Configure UserService.selectUserByOpenid(...).

final UserInfo userInfo = new UserInfo();

userInfo.setUserId("userId");

userInfo.setUserName("userName");

userInfo.setNickName("nickName");

userInfo.setOpenid("openid");

userInfo.setUserPhone("userPhone");

userInfo.setAvatarUrl("avatarUrl");

userInfo.setGender(0);

userInfo.setCreateTime("createTime");

userInfo.setRegistrationCode("registrationCode");

userInfo.setUpdateTime("updateTime");

when(mockUserService.selectUserByOpenid("openid")).thenReturn(userInfo);

when(mockGiftInfoMapper.selectUserExchange("openid")).thenReturn(Arrays.asList(0));

// Run the test

final List<GiftInfo> result = giftHandlerServiceImplUnderTest.selectGiftList("openid");

// Verify the results

assertThat(result).isEqualTo(Collections.emptyList());

}

}

生成的代码说明,以查询方法SelectGiftLis为例:如果是测试service接口,一般使用serviceImpl来写测试用例,serviceImpl中一般会引入mapper接口。

测试代码中一般都是先生成一个对象,传入mapper接口方法的参数中,并且会创建一个mapper接口的返回对象。然后在使用serviceImpl来测试查

询方法,mock一个同样的查询参数,serviceImpl查询时就会有返回值。最后比对mapper接口返回的结果和serviceImpl查询返回的结果是否一致。

一致则通过测试,不一致则测试不通过。

点击如下图中的执行即可,效果如下.

有执行不成功的方法,自己在稍微修改一下测试的代码即可。

再次执行结果全部通过.

IDAE插件Squaretest是收费的,免费使用时间为30天。个人版本收费价格为35美元,有破解版本的小伙伴可以分享一下。

参考文章:https://zhuanlan.zhihu.com/p/318426230

完成第一步单元测试,下一步还需要收集测试之后的代码覆盖率。

添加依赖如下.

<dependency>

<groupId>org.jacoco</groupId>

<artifactId>jacoco-maven-plugin</artifactId>

<version>0.8.3</version>

</dependency>

配置maven plugin 插件.

<plugin>

<groupId>org.jacoco</groupId>

<artifactId>jacoco-maven-plugin</artifactId>

<version>0.8.3</version>

<configuration>

<includes>

<include>com/**/*</include>

</includes>

</configuration>

<executions>

<execution>

<id>pre-test</id>

<goals>

<goal>prepare-agent</goal>

</goals>

</execution>

<execution>

<id>post-test</id>

<phase>test</phase>

<goals>

<goal>report</goal>

</goals>

</execution>

</executions>

</plugin>

参考博文.

https://www.cnblogs.com/fnlingnzb-learner/p/10637802.html

依次执行clean/compile/test

遇到问题,没有生成测试报告,也没报错信息。查看控制台信息,发现单元测试被跳过执行。

修改配置后,继续执行,发现如下信息,Skipping JaCoCo execution due to missing execution data file.

去必应搜索查找原因,

https://www.cnblogs.com/trimphNuan/p/13863269.html

说是配置文件中配置了argLine 配置项,导致出现问题,去除后重新执行,代码覆盖率生成成功。

可以点击进入查看每一行代码的覆盖率。绿色的表示测试时已经已经覆盖到该行的代码,粉色的表示未覆盖到。

至此,单元测试操作,并且生成代码覆盖率完成。

最后可以参考一下阿里巴巴写的一篇关于单元测试的博文:《5个编写技巧,有效提高单元测试实践》

https://mp.weixin.qq.com/s/wQjFlXbK3MqKTUX2TfRR0g

使用Mockito与Squaretest进行单元测试.的更多相关文章

  1. 基于mockito做有效的单元测试

    概述 本文讲解的主要是有效和单元的思想,并不是说如何编写单元测试,用于改善和提高开发效率.编码风格.编码可读性和单测效率,不盲目追求覆盖率. 背景 现在很多单元测试只是利用@Test注解把代码或者整个 ...

  2. dubbo应用程序的单元测试环境搭建(springtest,powermock,mockito)

    转:http://blog.csdn.net/yys79/article/details/66472797 最近,项目中频繁用到dubbo,而且java工程用引用了几十个关联系统的服务(如用户认证,基 ...

  3. [Java SE/Junit] 基于Java的单元测试框架Mockito

    Mockito 是一个模拟测试框架,主要功能是在单元测试中模拟类/对象的行为. 1 为什么要使用Mockito? Mock可以理解为创建一个虚假的对象,或者说模拟出一个对象.在测试环境中用来替换掉真实 ...

  4. junit+mock+spring-test构建后台单元测试

    from:从0开始,构建前后端分离应用 1. 一些基本概念 1.1 为什么要进行单元测试?我自己的理解是 1.能够快速发现问题.避免衍生BUG的出现     在对一些现有代码进行修改时,或者修改现有B ...

  5. 学习 Spring Boot:(二十九)Spring Boot Junit 单元测试

    前言 JUnit 是一个回归测试框架,被开发者用于实施对应用程序的单元测试,加快程序编制速度,同时提高编码的质量. JUnit 测试框架具有以下重要特性: 测试工具 测试套件 测试运行器 测试分类 了 ...

  6. Mockito图书馆

    转载:https://static.javadoc.io/org.mockito/mockito-core/2.12.0/org/mockito/Mockito.html#42 org.mockito ...

  7. Mockito 学习资料

    Mockito 学习资料 网址 单元测试指南:Mockito https://blinkfox.github.io/2018/11/15/hou-duan/java/dan-yuan-ce-shi-z ...

  8. Mockito鸡尾酒第一杯 单测Mock

    鸡尾酒 Mockito是Java的单元测试Mock框架. 它的logo是一杯古巴最著名的鸡尾酒Mojito, Mojito鸡尾酒,源自古巴的哈瓦那,带有浓厚的加勒比海风情. 并不浓烈,但是喝一杯下去, ...

  9. Mockito 简介

    Mockito 是一种 Java Mock 框架,主要是用来做 Mock 测试,它可以模拟任何 Spring 管理的 Bean.模拟方法的返回值.模拟抛出异常等等,在了解 Mockito 的具体用法之 ...

  10. Android Weekly Notes Issue #233

    Android Weekly Issue #233 November 27th, 2016 Android Weekly Issue #233 本期内容包括: 用Mockito做RxJava的单元测试 ...

随机推荐

  1. MySQL使用遇到问题总结

    1.mysql安装好后在控制台输入命令后无反应 这是就要注意: show databases; 第一:databases是要加"s"结尾 第二:如果加了s仍无反应,看是否加了&qu ...

  2. CE修改器入门:寻找指针基址

    上一步阐述了如何使用代码替换功能对付变化位置的数据地址,但这种方法往往不能达到预期的效果,所以我们需要学习如何利用指针,在本关的 Tutorial.exe 窗口下面有两个按钮,一个会改变数值,另一个不 ...

  3. 记一次在服务器上运行node.js程序时无法通过nohup xxx & 方式挂起的问题

    由于业务需求 每天要在服务器上整理一组数据,为了方便就用node.js来写了.但是运行的时候发现了一个问题 明明使用了nohup main.js &的方式后台运行了程序 但是一旦我关闭了she ...

  4. nginx入门之安装和启动

    1.安装环境 nginx 使用源码编译安装,环境及组件如下: make 环境 openssl-fips-2.0.10 pcre-8.44 zlib-1.2.11 nginx-1.10.2 需要注意各组 ...

  5. 苹果iOS 17.2年底推送:iPhone 15 Pro的自定义操作按钮功能升级

    据报道,苹果会在年底推送iOS 17.2版本,新版系统将会修复iPhone 15系列WiFi速度慢的问题. 与此同时,iOS 17.2将会带来翻译功能,iPhone 15 Pro的自定义操作按钮切换到 ...

  6. Intel 14代酷睿提前上架加拿大:涨价最多7%

    Intel将在10月17日正式发布14代酷睿,说白了就是13代酷睿升级版,代号就能说明一切--Raptor Lake Refresh. 首批发布的只是高端的K/KF系列,一共六款,分别是8+16 24 ...

  7. 【Sensor有点意思】之重要参数理解

    1.sensor 通过CMOS图像传感器感受环境光,输出图像供我们分析,通过sensor宣传册了解一下sensor性能和情况.下图以斯特威SC8238为例. 2. 跟sensor相关的重要参数: 2. ...

  8. 常用容器:动态数组array、列表list、队列 queue、map或字典、 集合、栈等等

    一般语言都会提供一些逻辑容器的实现,各个语言的实现方式不同:底层的数学算法应该差不多: 动态数组 `` 这个没啥可说的,就是一个数组,满了时候,再创建一个数组,把之前的数组里的数据移过来,销毁之前数组 ...

  9. MySQL-生成随机数字、字符串、日期、验证码及 UUID的方法

    一.生成随机数字 1. 生成 0 到 1 之间的随机数 MySQL 中的 RAND 函数可以用于生成一个大于等于 0 小于 1 的随机数字.例如: SELECT rand(); 该函数返回的数据类型为 ...

  10. UVALive7146 Defeat the Enemy

    题目链接 题目 见链接. 题解 知识点:贪心,STL. 首先要保证我方军队能消灭对方军队才行,因此只要我们按攻击力从大到小排,对方按防御力从大到小排,从大到小遍历,用我方所有攻击力大于敌方目前防御力军 ...