Junit单元测试使用

这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战

项目开发过程中,无论是对功能的自验测试,还是自动化用例的创建,总少不了单元测试的身影。单元测试常见于对Service层逻辑功能的测试,也会有针对Controller层的测试,此时需要使用JUnit提供的Mcok对象模拟请求测试。

1. @SpringBootTest

@SpringBootTest注解的作用是加载ApplicationContext,启动Spring容器,SpringBootTest注解会从当前包开始,自动检索程序的配置文件,逐级向上查找@SpringBootApplication注解和@SpringBootConfiguration注解的类。

@SpringBootTest注解中常见的配置项有:

  • value,指定配置属性
  • properties,指定配置属性,和value意义相同
  • classes,指定配置类,默认查找@Configuration类
  • webEnviroment,指定web环境,如MOCK、RANDOM_PORT、DEFINED_PORT、NONE

2. @RunWith(JUnit4)

当一个类使用@RunWith注解标注,或继承使用@RunWith注解标注的类时,JUnit会调用该类中引用的其他类来执行测试,而不是在JUnit内部去构建。

常见使用方式:@RunWith(SpringJUnit4ClassRunner.class)

JUnit4时,IDEA中不使用@RunWith注解,单元测试仍然可以正常运行,这是因为IDEA通过@SpringBootTest识别一个JUnit环境后,就相当于一个自识别的RunWith环境。而这种情况在其他IDE中是不存在的,因此标准的测试类中还是要使用@RunWith注解。

  • 注意:JUnit5中使用@ExtendWith(SpringExtension.class)代替@RunWIth注解,而SpringBoot环境中无需额外配置,因为@SpringBootTest注解中已经包含了@ExtendWith注解

3. @Test

@Test注解用于标注一个方法为单元测试方法,该方法可以单独执行

JUnit中类似的方法注解有:

  • @BeforeAll,在所有测试方法执行前执行一次,该注解标注的方法必须是static类型
  • @BeforeEach,每个测试方法执行前都会执行一次,常用于测试方法执行前初始化mockmvc对象

4. Mock

在面向对象的程序设计中,模拟对象(英语:mock object)是以可控的方式模拟真实对象行为的假对象。在编程过程中,通常通过模拟一些输入数据,来验证程序是否达到预期结果。

  • 使用模拟对象,可以模拟复杂的、真实的对象行为。如果在单元测试中无法使用真实对象,可采用模拟对象进行替代。
  • 使用Mockito一般分三个步骤:1、模拟测试类所需的外部依赖;2、执行测试代码;3、判断执行结果是否达到预期。

4.1 MockMvc简介

MockMvc是由spring-test包提供,实现了对Http请求的模拟,能够直接使用网络的形式,转换到Controller的调用,使得测试速度快、不依赖网络环境。同时提供了一套验证的工具,结果的验证十分方便。

4.2 引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
复制代码
  • SpringBoot项目会默认引入spring-boot-starter-test,其中包含了MockMvc内容。

4.3 创建MockMvc对象

  1. 使用MockMvcBuilder的build创建
    • MockMvcBuilder接口提供一个唯一的build方法,用来构造MockMvc实例对象。
    • MockMvc的实例化时有两种方式
      • 一种是使用StandaloneMockMvcBuilder;
      • 另外一种是使用DefaultMockMvcBuilder。
private MockMvc mockMvc;

@Autowired
private MineController mineController;
@Autowired
private WebApplicationContext webApplicationContext;

@BeforeEach
public void setup() {
   // 实例化方式一
   mockMvc = MockMvcBuilders.standaloneSetup(mineController).build();
   // 实例化方式二
   // mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
复制代码
  1. 使用注解创建
  • 直接使用注解注入MockMvc对象
 @Autowired
 private MockMvc mockMvc;
复制代码

4.4 请求服务

  1. mockMvc.perform,执行一个请求,并返回ResultActions对象
    • MockMvcRequestBuilders.get/post("XXX")构造一个请求
    • .contentType(),设置内容类型
    • .accept(MediaType.TEXT_HTML_VALUE))设置返回类型
    • .param(),添加请求传值
    • .params(),批量添加请求参数
    • .content(String content),设置请求体内容(jsonStr)
    • .header(),设置请求头内容
  2. ResultActions.andExpect(),添加执行完成后的断言。
    • 可以使用MockMvcResultMatchers来验证结果内容
    • .andExpect(MockMvcResultMatchers.status().is4xxClientError()),返回状态码4开头的错误
    • .andExpect(MockMvcResultMatchers.jsonPath("$.errors").exists()),返回内容下error节点
  3. ResultActions.andDo(),添加一个结果处理器,表示要对结果做点什么事情
    • MockMvcResultHandlers.print(),表示输出整个响应结果信息。
  4. ResultActions.andReturn(),执行完成后返回MvcResult结果对象。
  5. 使用断言对返回结果进行自定义验证

5. 断言

断言是单元测试中用于验证测试结果与期望值是否相符的方式,以此来判断单元测试是否通过。

  • JUnit5中断言方法是org.junit.jupiter.api.Assertions类中的静态方法
  • JUnit4中断言方法是org.junit.Assert类中的静态方法

常用断言方法

  • Assertions.assertNull/assertNotNull,断言预期的结果是否为null
  • Assertions.assertEquals/assertNotEquals,断言预期结果和实际指定结果是否相等
  • Assertions.assertTrue/assertFalse,断言预期结果是true或false
  • Assertions.assertArrayEquals,断言预期结果数组是否与指定数组相等
  • Assertions.assertTimeout,断言请求时间是否超时

Guess you like

Origin juejin.im/post/7055682721846132766