测试类写法以及几种常用方式
目录
- 为什么需要测试类
- 常用的jar包
- 测试模拟接口调用
- 测试Restful接口
- 通过Mock模拟方法调用结果
- 判读方法调用次数
- 注意事项
为什么需要测试类
方便模拟验证已完成功能
开发过程中,代码完成之后,在正式提交测试之前,往往需要自己对功能进行自查,修改一些明显的问题。但是有时候由于本地环境限制,实际流程和数据难以模拟,为了不影响其他模块,我们可以只针对自己新增加的功能进行测试。这时可以使用测试类,针对自己的接口,模拟特定的数据和环境,将测试的接口返回值与预期返回值进行对比,完成验证测试。
方便后期维护
由于项目开发过程中,经常有需求变更,有时候会有涉及范围很广的改动,有完善的测试类,可以在大面积改动的时候,检查出一些明显的问题,针对改动能对项目掌控的更好,节省测试时间,减少工作量。
常用的jar包
org.junit.* Junit4 框架
是通用的测试 java 程序的测试框架JUnit可以对Java代码进行白盒测试。
org.junit.Assert.* 断言,用于对比结果是否符合预期,用来判断测试结果的常用框架
org.mockito.* mock
也叫打桩,用来模拟数据,模拟方法调用
下面以SpringBoot为例,展示下测试类的具体使用
测试模拟接口调用
有接口 TestService 参数为String name 返回结果是 "Hello " + name
@Service
public class TestServiceImpl implements TestService {/*** 测试接口*/@Overridepublic String testInterface(String name) {return "Hello " + name;}
}
这是我们的测试类
@RunWith(SpringRunner.class)
@ActiveProfiles("ut")
@SpringBootTest
public class SiteCacheTest extends BaseTest {@Autowiredprivate TestService testService ;@Testpublic void testInterface() {String result = testService.testInterface("Tom");Assert.assertEquals("Hello Tom", result );}
}
测试结果是运行成功,这是一个很简单的例子,没有复杂的参数和业务逻辑,接口内部也没有对其他接口的调用。
在这个测试类中
@ActiveProfiles(“ut”) 表示该测试运行时使用的是 application-ut.properties配置文件,我们实际开发工作中,往往会有多个环境,可以给测试类指定环境,方便控制测试,以及防止测试数据对实际环境造成影响。
@SpringBootTest 该注解表示这个类是一个SpringBoot测试类
Assert.assertEquals(“Hello Tom”, result )
该方法接收两个参数,前者为期望值,后者为实际值,如果不一致,会测试失败
Assert还有很多类似的方法,常用的有
1 - Assert.fail()
让测试直接出错,抛出 AssertionError 。
2 - Assert.fail(String message)
让测试直接出错,并在抛出 AssertionError 时输出 message 作为错误提示信息。
3 - Assert.assertNull(Object object)
猜测 object 为 null,如果不为 null ,抛出 AssertionError 。
4 - Assert.assertSame(Object expected, Object actual)
猜测 expected 对象和 actual 对象引用的是同一个对象。 如果不同,抛出 AssertionError 。
5 - Assert.assertNotSame(Object expected, Object actual)
猜测 expected 对象和 actual 对象引用不同的对象。 如果相同,抛出 AssertionError 。
6 - Assert.assertTrue(boolean condition)
猜测 condition 为 true 。 如果为 false ,抛出 AssertionError 。
7 - Assert.assertFalse(boolean condition)
猜测 condition 为 false 。 如果为 true , 抛出 AssertionError 。
8- Assert.assertEquals(long expected, long actual)
猜测两个 long 类型 expected 和 actual 的值相等。 如果不相等,抛出 AssertionError 。
9 - Assert.assertNotEquals(long unexpected, long actual)
猜测两个 long 类型 unexpected 和 actual 的值不相等。 如果相等,抛出 AssertionError 。
测试Restful接口
前后台返利开发中,针对给前台调用的接口,经常会有一些500错误等,可以模拟请求,根据接口路径来模拟前端调用
通常会传一些错误参数来验证返回错误信息的情况。
@ActiveProfiles("ut")
@RunWith(SpringRunner.class)
@SpringBootTest
public class ControllerTest {@Autowiredprivate WebApplicationContext wac;private MockMvc mvc;@Beforepublic void setUp() {mvc = MockMvcBuilders.webAppContextSetup(wac).build(); //初始化MockMvc对象}@Testpublic void testController() throws Exception {String json = "{\n" +"\t\"username\": \"admin\",\n" +"\t\"password\": \"1234\"\n" +"}";String json1 = "{\n" +"\t\"username\": null,\n" +"\t\"password\": \"1234\"\n" +"}";mvc.perform(MockMvcRequestBuilders.post("/test/login").contentType(MediaType.APPLICATION_JSON_UTF8).accept(MediaType.APPLICATION_JSON_UTF8).content(json1.getBytes()))//传json参数.andExpect(MockMvcResultMatchers.status().isOk()).andDo(MockMvcResultHandlers.print());mvc.perform(MockMvcRequestBuilders.post("/test/login").contentType(MediaType.APPLICATION_JSON_UTF8).accept(MediaType.APPLICATION_JSON_UTF8).content(json.getBytes()))//传json参数.andExpect(MockMvcResultMatchers.status().isInternalServerError()).andDo(MockMvcResultHandlers.print());}}
如上,我们传正常的参数时,期望返回200, 即 MockMvcResultMatchers.status().isOk()
传参数错误时返回 500, 即MockMvcResultMatchers.status().isInternalServerError()
在这个测试类中
首先需要引入WebApplicationContext 用来模拟前台接口调用
@Before 该注解注解的方法,会在测试运行之前先运行,一般用于准备测试数据,初始化对象等,在此例中,我们用来初始化测试用的MockMvc 对象。
@Autowired 测试类可以像正常的类一样,注入你所需要的对象
MockMvcRequestBuilders 来指定测试接口路径,以及请求方式
.andExpect 类似断言, 来指定期望值。
通过Mock模拟方法调用结果
在开发过程中,类都不是独立的,往往一个方法的实现,需要调用多个不同地方的方法组合来实现一个功能,在测试中,我们需要其他方法的返回值满足我们的测试需要,这个时候可以使用@Spy注解来包装某个类,控制它的方法返回值。
下面看例子
@RunWith(SpringRunner.class)
@ActiveProfiles("ut")
@SpringBootTest
public class MockTest {@Spy@Autowiredprivate TestService testService;@Beforepublic void setUp() {MockitoAnnotations.initMocks(this);}@Testpublic void codeTest() {Mockito.when(testService.getUUID()).thenReturn("cdc60ad5609ddced1b128c60ac92340d");}}
在这个测试类中,testService中存在一个方法getUUID(),是返回随机id的,但是在我们要测试的方法中调用了这个方法,我们需要用到这个uuid,来模拟数据,以便测试我们的接口,比如我们需要根据它去另外一张表查询数据,但是我们不知道调用时随机的uuid是什么,这时候可以指定它的返回值,当testService.getUUID()被调用时,返回一个指定的值,这样我们就可以继续操作了。
@Spy 对一个注入的类进行包装,以便可以模拟方法返回值
我们需要使用 MockitoAnnotations.initMocks(this); 来初始化对象,该方法会对使用了**@Spy**的类进行初始化。
然后我们可以针对初始化过的对象来模拟返回值。
Mockito.when(xxx).thenReturn(xxx);
从字面可以看出,当…的时候返回…
需要注意的是when(…) thenReturn(…)会调用真实的方法,如果你不想调用真实的方法而是想要mock的话
就使用 doReturn(…) when(…) 不会调用真实方法
判读方法调用次数
有些时候针对循环和和判断较多,或者业务逻辑较为复杂的场景,需要判断方法调用次数。 还有一个场景是判断缓存是否生效,对于加了缓存的方法,多次调用,一般只有一次实际的调用,可以用这个方法来判断调用次数。
@RunWith(SpringRunner.class)
@ActiveProfiles("ut")
@SpringBootTest
public class CallTimesTest {@MockBeanprivate TestDao testDao;@Autowiredprivate TestService testService;@Testpublic void testCallTimes() {//设置第一次返回,第二次返回when(testDao.findUserByName(1)).thenReturn("user1").thenReturn("user2");String user1 = testService.findUserByName(1);Assert.assertEquals("user1", user1);String user2 = testService.findUserByName(1);Assert.assertEquals("user1", user1);verify(testDao, times(1)).findWithFullNameByTaskId(1);}
假设 testService 的findUserByName 方法内部是调用的 testDao的findUserByName方法,我们首先使用**@MockBean** 注解 注解testDao ,对其进行包装,然后我们可以对其进行模拟 ,设置第一次调用返回user1,第二次调用返回user2, 然后testService调用两次,如果在testDao的findUserByName方法上加了缓存,那么对于同样的入参,实际上只会调用一次。
我们可以使用verify来验证方法调用次数。
需要注意的是,findUserByName 方法这里我们的入参是1,在mock中我们有时候不需要写死参数,而是符合一定条件的参数即可,mock提供了一系列方法指定参数,如下图
注意事项
- 测试要注意覆盖率,不要只测试正确的情况,也要测试异常的情况
- 要模拟方法调,设定返回值需要先对类进行包装,@Mock 和@Spy注解均可以实现,区别在于前者是虚假的调用,而且不能mock自动装配的Bean,需要和@InjectMock配合使用;而后者监测真实的调用,方法实际上真的调用了,使用时要注意,想要不调用,可以使doReturn(…) when(…)。
- 在maven项目中,不设置skiptest=true的话,在打包时会默认先执行一遍测试类,所以要注意设置测试类运行环境,以免测试数据对正式环境造成污染,导致不必要的错误,更为规范的做法是,在每个测试用例中,最后对测试数据进行删除。
测试类写法以及几种常用方式相关推荐
- java 解析/操作 xml 几种常用方式 xml的增加/删除/修改
java 解析/操作 xml 几种常用方式 xml的增加/删除/修改 首先,我们先介绍几种常用的xml解析器. 1. 介绍 1)DOM(JAXP Crimson解析器) DOM是用与平台和语言无关的方 ...
- Ngnix安装的几种常用方式
Ngnix安装的几种常用方式 本文介绍了如何安装NGINX开源. 在稳定版还是主线版之间进行选择 在预编译的程序包和从源代码进行编译之间进行选择 安装预编译包 预建套件中包含的模块 安装预建的Cent ...
- 文件操作的几种常用方式
文件操作的几种常用方式,看起来有很多类型,然而无非是三种,读(r),写(w),追加(a),主要简单介绍下这几种常用方式. 更多学习链接:https://www.nhooo.com/python/pyt ...
- 【方法整理】Oracle 获取trace跟踪文件名的几种常用方式
[方法整理]Oracle 获取trace跟踪文件名的几种常用方式 1 BLOG文档结构图 2 前言部分 2.1 导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其 ...
- Silve37.Silverlight和ASP.NET相互传参的两种常用方式(QueryString,Cookie)
在本节中将讲述Silverlight和ASP.NET页面的相互传参的两种常用方式:Cookie和QueryString.首先我们新建一个名 为SLConnectASP.NET的Silverlight应 ...
- Windows校验文件哈希hash的两种常用方式
大家经常都到哪儿去下载软件和应用程序呢?有没想过下载回来的软件.应用程序或资源是否安全呢?在 Windows 10 和 Office 2016 发布当初,很多没权限的朋友都使用第三方网站去下载安装映像 ...
- it有啥好咨询的_蓝盟浅析,IT外包的四种常用方式
IT外包服务主要分为IT运维外包和软件开发外包,对于软件开发外包主要偏于研发类型,在本文中主要讨论IT运维外包. 上海蓝盟认为,IT运维外包主要包含IT服务外包.IT采购.弱电工程.系统集成和云服务等 ...
- html中img显示图片的两种常用方式
html中img显示图片的两种常用方式 显示图片,尤其是二维码的时候,大都是自动生成的,所以就需要能够从后台返回字符串,前台浏览器进行解析.好了,下面是这两种方式. 1. <img src=&q ...
- asp.net html silverlight 传参数,Silverlight和ASP.NET相互传参的两种常用方式(QueryString,Cookie)...
Silverlight实用窍门系列:37 程兴亮,网名煦风满裳 在本节中将讲述Silverlight和ASP.NET页面的相互传参的两种常用方式:Cookie和QueryString.首先我们新建一 ...
- python 读写数据文件的6种常用方式
本文主要介绍python读写数据文件的6种常用方式. 1. python内置方法 with open(r'test.xlsx') as f:a = f.read() 一般,在应用上述上下文管理器后,可 ...
最新文章
- Csharp: 拼音转汉字字符搜索字符串
- PowerShell批量设置PATH环境变量
- OutOfRangeError closed and has insufficient elements (requested 512, current size 362)
- GDCM:gdcm::Version的测试程序
- python中函数定义可以不包括什么_Python 中,函数定义可以不包括以下_______。
- Javascript学习数据结构--集合(Set实现)
- faster rcnn论文_论文导读-从Faster-RCNN/Mask RCNN/Cascade-RCNN到HTC
- 融云联合ofo给大家送福利!
- mysql 纯真ip 导出dat_纯真IP数据库(qqwry.dat)转换成最新的IP数据库格式(ipwry.dat)
- 盘点python socket 中recv函数的坑
- 设置div背景颜色透明度,内部元素不透明
- 指数分布的样本和是充分统计量
- 人生的第一篇博客φ(>ω<*)
- 使用‘终端’融合磁盘然后进行MAC重装系统
- 2021-09-29破解小米“铁蛋”,只需9999元,你也可以做一个四足机器人!
- 一元二次求解matlab程序,规范MATLAB编程实例——求解一元二次方程
- 石墨文档(协同开发)
- (数字ic验证)从零开始的apb_watchdog验证模块搭建(一、功能介绍与环境搭建)
- 【哈希】购物券(bday)
- 鸡兔同笼python程序怎么写_【鸡】鸡的功效_鸡图片_食材百科_美食杰
热门文章
- Java扫雷游戏的设计与实现毕业设计论文
- 【测绘程序设计】C#将度分秒(° ‘ “)转换度(°)程序实现(附源码)
- Java自学路线图之Java进阶自学
- win10 Visio软件运行 闪退
- 求 s = a+aa+aaa+… …+aaa…a的值,其中a是一个数字
- 【ArcGIS教程03】基础知识(建议收藏)
- 【小程序demo】带你玩转支付宝小程序之小程序二维码
- 水系图一般在哪里找得到_如何对于排水系统的服务范围进行统计分析
- 点云 数据 (偏向于研究大小)
- apache comments io包IOUtils方法简单介绍