五分钟技术趣谈 | Java常用的单元测试框架介绍
haoteby 2024-12-15 13:12 19 浏览
本文主要讲述java常用的单元测试框架,包括junit5、Mockito、SpringBootTest框架,通过讲解各框架常用注解、使用样例、注意事项,让大家在开发过程中能够快速、高效选择适合自己的单元测试框架。
作者:孟祥路
单位:中移(杭州)信息技术有限公司
Part 01
● JUnit5框架 ●
1.1 Junit5介绍
Junit5需要Java 8或更高版本,和Junit4只是一个单独的Jar包不同,目前的Junit5组成如下:JUnit5=JUnit Platform+JUnit Jupiter+JUnit Vintage
- JUnit Platform:
是Junit向测试平台演进,提供平台功能的模块,通过JUnit Platform,其他的自动化测试引擎或开发人员自己定制的引擎都可以接入Junit实现对接和执行
- JUnit Jupiter:
这是Junit5的核心,可以看作是承载Junit4原有功能的演进,它包含了很多丰富的新特性来使JUnit自动化测试更加方便、功能更加丰富和强大。
本系列就会重点围绕Jupiter中的一些特性进行介绍。Jupiter本身也是一个基于Junit Platform的引擎实现。
- JUnit Vintage:
Junit发展了10数年,Junit3和Junit4都积累了大量的用户,作为新一代框架,这个模块是对JUnit3,JUnit4版本兼容的测试引擎,使旧版本Junit的自动化测试脚本也可以顺畅运行在Junit5下,它也可以看作是基于Junit Platform实现的引擎范例。
1.2 测试实例生命周期介绍
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
* PER_METHOD(默认):JUnit在执行每个测试方法之前创建每个测试类的新实例
* PER_CLASS:JUnit Jupiter在同一个测试实例上执行所有测试方法,当使用这种模式时,每个测试类将创建一个新的测试实例。因此,如果您的测试方法依赖于存储在实例变量中的状态,则可能需要在@BeforeEach或@AfterEach方法中重置该状态。
1.3 Junit5常用注解介绍
@BeforeAll
JUnit5@BeforeAll注释是JUnit4中@BeforeClass注释的替代。它用于表示应在当前测试类中的所有测试方法之前执行的带的方法。
备注:@BeforeAll注释的方法必须是静态方法,否则会报运行时错误。
@BeforeEach
JUnit5@BeforeEach注释替代了JUnit4中的@Before注释。被注释的方法会在当前类中的每个Test方法之前执行。也就是说有多少个test这个方法就会执行多少次。
备注:@BeforeEach注释的方法一定不能是静态方法,否则会报发运行时错误。
@AfterEach
JUnit5@AfterEach注释是JUnit4中@After注释的替换。它用于表示应在当前类中的每个@Test方法之后执行带注释的方法。
@AfterAll
JUnit5@AfterAll注释是JUnit4中@AfterClass注释的替换。它用于表示应在当前测试类中的所有测试之后执行带注释的方法。
备注:@AfterAll注释的方法必须是静态方法,否则会报运行时错误。
Junit5当中使用@BeforeEach替换了@Before使用 @AfterEach替换了@After
@Disabled可以用于不运行某些test的场景。
@Tag可以用于将测试分类。
JUnit Jupiter支持下列注解,用于配置测试和扩展框架。
所有核心注解位于junit-jupiter-api模块中的org.junit.jupiter.api包中。
Part 02
● spring-boot-test框架 ●
2.1 版本迭代
在JUnit4中,自定义框架通常意味着使用@RunWith注释来指定一个自定义的运行器。使用多个运行器是有问题的。
Junit5在Spring boot 2.1.x之前,@SpringBootTest需要配合@ExtendWith(SpringExtension.class)才能正常工作的。
而在Spring boot 2.1.x之后,我们查看@SpringBootTest 的代码会发现,其中已经组合了@ExtendWith(SpringExtension.class),因此,无需在进行该注解的使用了。
Spring Boot 2.2.0版本开始引入JUnit5作为单元测试默认库
Junit5中包含JUnit Vintage:这个模块是兼容JUnit3、JUnit4版本的测试引擎,使得旧版本的自动化测试也可以在JUnit5下正常运行。防止使用旧的junit4相关接口,可以进行依赖排除,如下图:
SpringBoot 2.4以上版本移除了默认对Vintage的依赖。如果需要兼容JUnit4.x版本,需要自行引入。
SpringBootTest默认集成了以下功能:
备注:JUnit4前移注意事项
2.2 Spring Boot Test中的主要注解
从功能上讲,Spring Boot Test中的注解主要分如下几类:
2.2.1 配置类型的注解
使用@SpringBootApplication启动测试或者生产代码,被@TestComponent描述的Bean会自动被排除掉。如果不是则需要向@SpringBootApplication添加TypeExcludeFilter。
2.2.2 mock类型的注解
@MockBean和@SpyBean这两个注解,在mockito框架中本来已经存在,且功能基本相同。Spring Boot Test又定义一份重复的注解,目的在于使MockBean和SpyBean被ApplicationContext管理,从而方便使用。MockBean和SpyBean功能非常相似,都能模拟方法的各种行为。不同之处在于MockBean是全新的对象,跟正式对象没有关系;而SpyBean与正式对象紧密联系,可以模拟正式对象的部分方法,没有被模拟的方法仍然可以运行正式代码。
@MockBean 只能 mock 本地的代码——或者说是自己写的代码,对于储存在库中而且又是以 Bean 的形式装配到代码中的类无能为力。
@SpyBean 解决了 SpringBoot 的单元测试中
@MockBean 不能 mock 库中自动装配的 Bean 的局限
2.2.3 自动配置类型的注解(@AutoConfigure*)
这些注解可以搭配@\*Test使用,用于开启在@\*Test中未自动配置的功能。例如@SpringBootTest和@AutoConfigureMockMvc组合后,就可以注入org.springframework.test.web.servlet.MockMvc。
2.2.3.1 自动配置类型有两种使用方式
a.在功能测试(即使用@SpringBootTest)时显示添加。
b.一般在切片测试中被隐式使用,例如@WebMvcTest注解时,隐式添加了@AutoConfigureCache
@AutoConfigureWebMvc
@AutoConfigureMockMvc。
2.2.4 启动测试类型的注解
所有的@*Test注解都被@BootstrapWith注解,它们可以启动。
ApplicationContext,是测试的入口,所有的测试类必须声明一个@*Test注解。
除了@SpringBootTest之外的注解都是用来进行切面测试的,他们会默认导入一些自动配置。一般情况下,推荐使用@SpringBootTest而非其它切片测试的注解,简单有效。若某次改动仅涉及特定切片,可以考虑使用切片测试。
2.2.5 常用配置介绍
@SpringBootTest,其中包含的配置项如下:
@WebEnvironment,其中包含的配置项如下:
Part 03
● Mockito框架 ●
3.1 常用的Mockito方法
3.2 Mockito参数适配方法
Mockito.anyString()
Mockito.anyInt()
Mockito.anyLong()
Mockito.anyDouble()
Mockito.anyObject() 表示任何对象
Mockito.any(clazz) 表示任何属于clazz的对象
Mockito.anyCollection()
Mockito.anyCollectionOf(clazz)
Mockito.anyList(Map, set)
Mockito.anyListOf(clazz)
注:Mockito.anyString() 不能匹配到 null 参数,如果还需要匹配 null,可以使用 Mockito.any()。
Part 04
● 单元测试样例 ●
4.1 Mock redis、kafka方法
方法1:
@SpringBootTest通过@Resource引入对象测试,需要依赖redis环境(会启动spring boot 容器)
方法2:
//声明变量
private AsyncService asyncService;
//需要mock的对象
private StringRedisTemplate stringRedisTemplate;
//创建要测试对象
asyncService = new AsyncServiceImpl();
//mock对象(也可以使用@Mock注解方式)
StringRedisTemplate stringRedisTemplate =
mock(StringRedisTemplate.class,Mockito.RETURNS_DEEP_STUBS);
KafkaProducer kafkaProducer = mock(KafkaProducer.class);
//属性赋值
ReflectionTestUtils.setField(asyncService,
"stringRedisTemplate", stringRedisTemplate);
ReflectionTestUtils.setField(asyncService,
"kafkaProducer", kafkaProducer);
@Test
@DisplayName("mock redis、kafka 测试")
public void redisTest() {
when(stringRedisTemplate.opsForValue().get(anyString())).thenReturn("2222");
Assertions.assertTrue(asyncService.testRedis("真实方法调用"));
}
4.2 Spring Security模拟登录方法
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<version>5.6.5</version>
<scope>test</scope>
</dependency>
注解:@WithMockUser(roles = "ROOT", username = "root")
4.3 远程接口调用方法(Controller入口测试)
- MockMVC的基本步骤
(1) mockMvc.perform执行一个请求。
(2) MockMvcRequestBuilders.get("XXX")构造一个请求。
(3) ResultActions.param添加请求传值
(4) ResultActions.accept()设置返回类型
(5) ResultActions.andExpect添加执行完成后的断言。
(6) ResultActions.andDo添加一个结果处理器,表示要对结果做点什么事情,比如处使用print()输出整个响应结果信息。
(7) ResultActions.andReturn表示执行完成后返回相应的结果。
相关推荐
- 网站seo该怎么优化
-
一、网站定位在建设一个网站之前,我们首先要做的就是一个网站清晰的定位,会带来转化率相对较高的客户群体,我们建站的目的就是为了营销,只有集中来做某一件事,才会更好的展现我们的网站。在做SEO优化的同时...
- 3个小技巧教你如何做好SEO优化
-
想半路出家做SEO?可是,怎么才做的好呢?关于SEO专业技术弄懂搜索引擎原理,咱们做搜索引擎排名的首先就是要了解搜索引擎的工作原理,对SEO优化有更深入了解之后再来做SEO,你就能从搜索引擎的视点...
- SEO指令分享:filetype指令
-
filetype用于搜索特定的文件格式。百度和谷歌都支持filetype指令。比如搜索filetype:pdf今日头条返回的就是包含今日头条这个关键词的所有pdf文件,如下图:百度只支持:pdf...
- 网站seo优化技巧大全
-
SEO在搜索引擎中对检索结果进行排序,看谁最初是在用户的第一眼中看到的。实际上,这些排名都是通过引擎的内部算法来实现的。例如,百度算法很有名。那么,对百度SEO的优化有哪些小技巧?下面小编就会说下针对...
- 小技巧#10 某些高级的搜索技巧
-
由于某些原因,我的实验场所仅限百度。1.关键词+空格严格说来这个不能算高级,但关键词之间打空格的办法确实好用。我习惯用右手大拇指外侧敲击空格键,这个习惯在打英文报告时尤其频繁。2.site:(请不要忽...
- MYSQL数据库权限与安全
-
权限与安全数据库的权限和数据库的安全是息息相关的,不当的权限设置可能会导致各种各样的安全隐患,操作系统的某些设置也会对MySQL的安全造成影响。1、权限系统的工作原理...
- WPF样式
-
UniformGrid容器<UniformGridColumns="3"Rows="3"><Button/>...
- MySQL学到什么程度?才有可以在简历上写精通
-
前言如今互联网行业用的最多就是MySQL,然而对于高级Web面试者,尤其对于寻找30k下工作的求职者,很多MySQL相关知识点基本都会涉及,如果面试中,你的相关知识答的模糊和不切要点,基...
- jquery的事件名称和命名空间的方法
-
我们先看一些代码:当然,我们也可以用bind进行事件绑定。我们看到上面的代码,我们可以在事件后面,以点号,加我们的名字,就是事件命名空间。所谓事件命名空间,就是事件类型后面以点语法附加一个别名,以便引...
- c#,委托与事件,发布订阅模型,观察者模式
-
什么是事件?事件(Event)基本上说是一个用户操作,如按键、点击、鼠标移动等等,或者是一些提示信息,如系统生成的通知。应用程序需要在事件发生时响应事件。通过委托使用事件事件在类中声明且生成,且通过...
- 前端分享-原生Popover已经支持
-
传统网页弹窗开发需要自己处理z-index层级冲突、编写点击外部关闭的逻辑、管理多个弹窗的堆叠顺序。核心优势对比:...
- Axure 8.0 综合帖——新增细节内容
-
一、钢笔工具与PS或者AI中的钢笔工具一样的用法。同样有手柄和锚点,如果终点和起点没有接合在一起,只要双击鼠标左键即可完成绘画。画出来的是矢量图,可以理解为新的元件。不建议通过这个工具来画ICON图等...
- PostgreSQL技术内幕28:触发器实现原理
-
0.简介在PostgreSQL(简称PG)数据库中,触发器(Trigger)能够在特定的数据库数据变化事件(如插入、更新、删除等)或数据库事件(DDL)发生时自动执行预定义的操作。触发器的实现原理涉及...
- UWP开发入门(十七)--判断设备类型及响应VirtualKey
-
蜀黍我做的工作跟IM软件有关,UWP同时会跑在电脑和手机上。电脑和手机的使用习惯不尽一致,通常我倾向于根据窗口尺寸来进行布局的变化,但是特定的操作习惯是依赖于设备类型,而不是屏幕尺寸的,比如聊天窗口的...