SpringBoot2中JUnit5单元测试总结

SpringBoot2中JUnit5单元测试总结


1、JUnit5整体概述

JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

JUnit Platform: Junit Platform是在JVM上启动测试框架的基础,不仅支持Junit自制的测试引擎,其他测试引擎也都可以接入。
JUnit Jupiter: JUnit Jupiter提供了JUnit5的新的编程模型,是JUnit5新特性的核心。内部 包含了一个测试引擎,用于在Junit Platform上运行。
JUnit Vintage: 由于JUint已经发展多年,为了照顾老的项目,JUnit Vintage提供了兼容JUnit4.x,Junit3.x的测试引擎。

2、JUnit5 使用添加依赖


<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <scope>test</scope>
</dependency>

3、创建完成,默认结构


!!!import org.junit.jupiter.api.Test; //注意这里使用的是jupiter的Test注解!!不是junit中的test

@SpringBootTest//这个是可以启动整个项目进行测试
class XiaoKeWebAdminApplicationTests {


    @Test//标记这个方法要被测试
    void testFunc() {
			System.out.println("Junit5测试开始...")
    }
}

4、JUnit5常用注解


  • @Transactional 标注测试方法,测试完成后自动回滚,在服务层测试时与数据库交互使用,可以回滚数据中的测试数据
  • @Test :表示方法是测试方法。但是与JUnit4的@Test不同,他的职责非常单一不能声明任何属性,拓展的测试将会由Jupiter提供额外测试
  • @ParameterizedTest :表示方法是参数化测试
  • @RepeatedTest :表示方法可重复执行
  • @DisplayName :为测试类或者测试方法设置展示名称
  • @BeforeEach :表示在每个单元测试之前执行
  • @AfterEach :表示在每个单元测试之后执行
  • @BeforeAll :表示在所有单元测试之前执行
  • @AfterAll :表示在所有单元测试之后执行
  • @Tag :表示单元测试类别,类似于JUnit4中的@Categories
  • @Disabled :表示测试类或测试方法不执行,类似于JUnit4中的@Ignore
  • @Timeout :表示测试方法运行如果超过了指定时间将会返回错误
  • @ExtendWith :为测试类或测试方法提供扩展类引用

5、断言(assertions)


断言(assertions)是测试方法中的核心部分,用来对测试需要满足的条件进行验证。这些断言方法都是 org.junit.jupiter.api.Assertions 的静态方法


assertEquals	      判断两个对象或两个原始类型是否相等
---
assertNotEquals	      判断两个对象或两个原始类型是否不相等
---
assertSame	          判断两个对象引用是否指向同一个对象
---
assertNotSame	      判断两个对象引用是否指向不同的对象
---
assertTrue	          判断给定的布尔值是否为 true
---
assertFalse	          判断给定的布尔值是否为 false
---
assertNull	          判断给定的对象引用是否为 null
---
assertNotNull	      判断给定的对象引用是否不为 null
---
assertArrayEquals 方法来判断两个对象或原始类型的数组是否相等
---
assertAll 方法接受多个 org.junit.jupiter.api.Executable 函数式接口的实例作为要验证的断言,可以通过 lambda 表达式很容易的提供这些断言
---
Assertions.assertThrows() ,配合函数式编程就可以进行使用。
---
Assertions.assertTimeout() 为测试方法设置了超时时间



6、前置条件(assumptions)

JUnit 5 中的前置条件(assumptions【假设】)类似于断言,不同之处在于不满足的断言会使得测试方法失败,而不满足的前置条件只会使得测试方法的执行终止。前置条件可以看成是测试方法执行的前提,当该前提不满足时,就没有继续执行的必要。

@DisplayName("前置条件测试类")
public class AssumptionsTest {
 private final String environment = "TEST";
 
 @Test
 @DisplayName("true or false")
 public void simpleAssume() {
    assumeTrue(Objects.equals(this.environment, "TEST"));
    assumeFalse(() -> Objects.equals(this.environment, "PROD"));
 }
 
 @Test
 @DisplayName("assumingthat ")
 public void assumeThenDo() {
    assumingThat(
       Objects.equals(this.environment, "TEST"),
       () -> System.out.println("In TEST")
    );
 }
}

assumeTrue 和 assumFalse 确保给定的条件为 true 或 false,不满足条件会使得测试执行终止。


assumingThat 的参数是表示条件的布尔值和对应的 Executable 接口的实现对象。只有条件满足时,Executable 对象才会被执行;当条件不满足时,测试执行并不会终止。


7、参数化测试

参数化测试是JUnit5很重要的一个新特性,它使得用不同的参数多次运行测试成为了可能,也为我们的单元测试带来许多便利。

利用@ValueSource等注解,指定入参,我们将可以使用不同的参数进行多次单元测试,而不需要每新增一个参数就新增一个单元测试,省去了很多冗余代码。

  • @ValueSource: 为参数化测试指定入参来源,支持八大基础类以及String类型,Class类型

  • @NullSource: 表示为参数化测试提供一个null的入参

  • @EnumSource: 表示为参数化测试提供一个枚举入参

  • @CsvFileSource:表示读取指定CSV文件内容作为参数化测试入参

  • @MethodSource:表示读取指定方法的返回值作为参数化测试入参(注意方法返回需要是一个流)

8、service层测试(和数据库交互)

服务层一般是要和数据库进行交互的,可以通过以下两个注解起到回滚数据的功能

  • //@Transactional

  • //@Rollback()

import cn.hutool.core.lang.Assert;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest//测试服务层必须要有这个,可以测试整个springboot工程
class XiaokeApplicationTests {

    @Autowired
    private TestService testService;//引入这个服务

    @Test
    //@Transactional
    //@Rollback(true) ,true回滚,false不回滚
    void insertTest() {
        User user = new User();
        user.setId("100");
        user.setName("xiaoke");
        user.setAge(30);
        
        testService.insert(user);
    }

}

9、controller层测试(模拟发送请求)

mport org.junit.Assert;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
 
@SpringBootTest
//测试环境使用,用来表示测试环境使用的ApplicationContext将是WebApplicationContext类型的
@WebAppConfiguration
class XiaokeApplicationTests {
 
    @Autowired
    private WebApplicationContext webApplicationContext;
    private MockMvc mockMvc;
 
    @BeforeEach
    public void setUp() throws Exception {
    	// 初始化MockMvc
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }
 
 	/**
         * 1、mockMvc.perform执行一个请求。
         * 2、MockMvcRequestBuilders.get("XXX")或者post()构造一个请求。
         * 3、ResultActions.param添加请求传值
         * 4、ResultActions.accept(MediaType.TEXT_HTML_VALUE))设置返回类型
         * 5、ResultActions.andExpect添加执行完成后的断言。
         * 6、ResultActions.andDo添加一个结果处理器,表示要对结果做点什么事情
         *   比如此处使用MockMvcResultHandlers.print()输出整个响应结果信息。
         * 7、ResultActions.andReturn表示执行完成后返回相应的结果。
         */
         
    @Test
    void contextLoads() throws Exception {
        
        		MvcResult mvcResult = mockMvc
        		.perform(MockMvcRequestBuilders
        		.get("/test")
                //.param("name", "xiaoke") 如果是post方式,则要添加param,构造body
                .accept(MediaType.APPLICATION_JSON))
                //等同于Assert.assertEquals(200,status);
                .andExpect(MockMvcResultMatchers.status().isOk())
                //等同于 Assert.assertEquals("hello world!",content);
                .andExpect(MockMvcResultMatchers.content().string("hello test!"))
                .andDo(MockMvcResultHandlers.print())
                .andReturn();
                
        //得到返回代码
        int status = mvcResult.getResponse().getStatus();
        //得到返回结果
        String content = mvcResult.getResponse().getContentAsString();
        //断言,判断返回代码是否正确
        Assert.assertEquals(200, status);
        //断言,判断返回的值是否正确
        Assert.assertEquals("hello test!", content);
    }
 
}
 
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值