当前位置: 首页 > article >正文

Junit与Spring Test简单使用

Junit与Spring Test简单使用

  • Junit5简介
    • Junit5 注解
    • Junit5与Spring结合
  • 差异概览
  • Mocking
    • @MockBean
    • @SpyBean
    • Demo
  • 注意事项

又要写测试代码了,总结记录一下。

Junit5简介

与单一模块设计的Junit4不同,Junit5引入了模块化架构,由三个主要子项目组成:

  • JUnit Platform:测试运行的基础平台,支持不同的测试引擎(不仅仅是 JUnit,还可以扩展其他测试框架,如 TestNG)。
  • JUnit Jupiter:JUnit5 的新编程模型和扩展模型,包含新的注解和测试方法(如 @Test, @BeforeEach,@AfterEach 等)。
  • JUnit Vintage:提供对 JUnit4 及更早版本的向后兼容支持,因此 JUnit5 可以运行旧的 JUnit4 测试代码。

Junit5 注解

  1. @BeforeEach 和 @AfterEach:取代了 JUnit4 的 @Before 和 @After,作用于每个测试方法。
  2. @BeforeAll 和 @AfterAll:取代了 JUnit4 的 @BeforeClass 和 @AfterClass,可以作用于整个类生命周期,且在 JUnit5 中可以是非静态方法(通过注入 TestInstance)。
  3. @DisplayName:允许为测试方法和类指定自定义名称,方便生成更具可读性的测试报告。
  4. @Nested:支持嵌套的测试类,便于组织复杂的测试场景。
  5. @ParameterizedTest:增强了参数化测试的支持,允许为测试方法传递多个参数集。
  6. DynamicTest:动态创建测试用例,支持灵活的测试流程。

@BeforeAll``@AfterAll 类级别,只执行一次

@BeforeEach @AfterEach 方法级别,每个方法都会执行

All 和 each的区别,在执行类级别测试时才能看出来: all仅执行一次,each执行次数取决于有多少个Test方法
在这里插入图片描述

Junit5与Spring结合

  • 在与Spring集成时,不再使用@RunWith
  • @ExtendWith, 指定拓展为Spring, 测试中可以使用Spring注解进行依赖注入,@ContextConfiguration指定配置类
  • @Transactional, 测试中提供事务支持
  • Spring框架提供的 @MockBean @SpyBean注解, 提供Mocking支持,模拟Bean行为

在springboot项目中,@SpringBootTest注解内部就是使用了
@ExtendWith({SpringExtension.class})`提前帮我们配置好了

差异概览

功能/特性JUnit4JUnit5Spring Test
架构单一模块模块化架构(Platform, Jupiter, Vintage)基于 TestContext 框架,与 JUnit 集成
注解@Test
, @Before
, @After
@Test
, @BeforeEach
, @AfterEach
@ContextConfiguration
, @Transactional
扩展机制@RunWith
, TestRule
@ExtendWith
, TestInstance
@ExtendWith(SpringExtension.class)
参数化测试较弱的参数化测试支持强大的参数化测试支持与 Spring 环境集成,支持 Mock 和依赖注入
事务管理N/AN/A支持 @Transactional
,测试完成后自动回滚
Spring 集成@RunWith(SpringJUnit4ClassRunner.class)@ExtendWith(SpringExtension.class)内置的对 Spring 上下文的管理和 Bean 注入支持

Mocking

@MockBean

如果不指定规则,则mockBean执行完返回默认值,即对象为null,数字为0

如果指定了规则,就按照规则返回,下面例子按照规则返回ok

@SpyBean

有规则按照规则走,没有规则按照真实服务进行。比如:在多服务调用过程中,如果部分服务不可用,可以定义规则,如果服务可用,则调用真实的服务。

Demo

import org.junit.jupiter.api.*;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.test.mock.mockito.SpyBean;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.doReturn;

@SpringBootTest
class DemoTestApplicationTests {
    @SpyBean
    MyService myService;// 所有方法使用myService方法,可自定义覆盖

    @MockBean
    MyService2 myService2; // 所有方法需要自定义返回,否则使用默认初始值或null

    // 调用Spy模拟服务,
    @Test
    void invokeSpy(){
        // 仅定义hello的mock规则
        doReturn("hello handsome").when(myService).hello("wyy");
        assertEquals("hello handsome", myService.hello("wyy"));

        // 未定义规则,直接调用say()逻辑
        assertEquals("hello", myService.say("hello"));
    }

    // 调用Mock模拟服务,
    @Test
    void invokeMock(){
        // 仅定义hello的mock规则
        doReturn("hello handsome").when(myService2).hello("wyy");
        assertEquals("hello handsome", myService2.hello("wyy"));

        // 未定义规则,返回初始值或null
        assertEquals("hello", myService2.say("hello"));
    }


    // All 和 each的区别,执行单独的测试方法区分不了,
    // 在执行类级别测试时才能看出来: all仅执行一次,each执行次数取决于有多少个Test方法
    @BeforeAll
    static void beforeAll(){
        System.out.println("before all");
    }

    @BeforeEach
    void beforeEach(){
        System.out.println("before each");
    }

    @AfterEach
    void afterEach(){
        System.out.println("after each");
    }

    @AfterAll
    static void afterAll(){
        System.out.println("after all");
    }
}

注意事项

  1. 使用断言进行判断,严禁System.out进行人工判断
  2. 丰富测试场景的多样性,通过不同参数测试增加多样性,提升测试覆盖率

http://www.kler.cn/news/316297.html

相关文章:

  • AI量化交易机器人开发
  • docker挂载宿主机文件run命令启动报错
  • 如何选购笔记本电脑?要看哪些参数?
  • C++重生之我是001
  • Flat File端口更新:如何实现嵌套结构
  • keil安装HAL库
  • 计算机网络32——Linux-文件io-2文件系统
  • 《拿下奇怪的前端报错》:nvm不可用报错`GLIBC_2.27‘‘GLIBCXX_3.4.20‘not Found?+ 使用docker构建多个前端项目实践
  • Linux环境Docker安装Mongodb
  • Electron 安装包 asar 解压定位问题实战
  • 深度学习与大模型第5课:利用 NLTK 中的朴素贝叶斯工具解决实际问题:垃圾邮件过滤
  • Java 速刷复习用极简小抄 P1 - Java 概念
  • C++学习笔记(36)
  • C++--C++11(下)
  • 近几年来说最有效率的编程语言和市场最认可的编程语言分别是什么?
  • Pandas库中pd.to_datetime()函数用法详细介绍
  • 监控易:部委-省-市-县多级架构的集中智能运维解决方案
  • Java如何操作Elasticsearch
  • Redis面试真题总结(三)
  • C++初阶:STL详解(四)——vector迭代器失效问题
  • 基于深度学习的3D场景重建
  • esp32 wifi 联网后,用http 发送hello 用pc 浏览器查看网页
  • WebLogic文件任意上传漏洞CVE-2018-2894
  • 0.设计模式总览——设计模式入门系列
  • uniapp如何实现图片轮播特效?
  • 二、MySQL环境搭建
  • ML 系列:机器学习和深度学习的深层次总结(07)数据预处理—解决缺失值、异常值和错误数据
  • 基于单片机的远程无线控制系统设计
  • FP7208:升压汽车车灯方案 高效稳定的电力支持
  • js笔记(二进制由0和1两个数字组成)