UT单元测试

Tips:在使用时一定要注意版本适配性问题

一、Mockito

1.1 Mock的使用

Mock 的中文译为仿制的,模拟的,虚假的。对于测试框架来说,即构造出一个模拟/虚假的对象,使我们的测试能顺利进行下去。

Mock 测试就是在测试过程中,对于某些 不容易构造(如 HttpServletRequest 必须在 Servlet 容器中才能构造出来)或者不容易获取 比较复杂 的对象(如 JDBC 中的 ResultSet对象),用一个 虚拟 的对象(Mock 对象)来创建,以便测试方法。

@Mock 注解用于创建模拟对象,而 @InjectMocks 注解用于注入依赖的模拟对象或真实对象到测试对象中。通常情况下,@Mock 和 @InjectMocks 会配合使用,在单元测试中提供模拟对象和被测试对象之间的依赖关系。

public class BookService {

    private BookRepository bookRepository;

    public BookService(BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }

    public Book findBook(String id) {
        return bookRepository.findById(id);
    }
}

@ExtendWith(MockitoExtension.class)
class BookServiceTest {

    @Mock
    private BookRepository bookRepository;

    @InjectMocks
    private BookService bookService;

    @Test
    void findBook() {
        Book book = new Book("1", "Title");
        when(bookRepository.findById("1")).thenReturn(book);

        bookService.findBook("1");

        verify(bookRepository, times(1)).findById("1");
    }
}

创建了一个模拟的 BookRepository,并且使用了 @InjectMocks 将它注入到了 BookService 的实例中。

1.2  @Mock @Spy @InjectMocks

  • @Mock:创建一个模拟对象(mocked object)。对其进行设置后,@Mock 创建的对象会返回设置好的值而不是执行真实的逻辑。
  • @Spy:创建一个间谍对象(spied object)。它和真实的对象很类似,除非明确设定,否则都是调用真实的方法。
  • @InjectMocks:创建一个实例,其余用 @Mock(或 @Spy)注解创建的mock会被注入到用 @InjectMocks 注解的类中。

Q1:既然@spy调用的是真实方法,那我为什么要使用这个注解呢,我直接在需要模拟的方法时候使用mock不就可以了吗

A:@Spy 是在你只想模拟类的部分行为,而其他方法还希望执行真实的逻辑时非常有用的。

@Spy
List<String> spyList = new ArrayList<String>();

@Test
public void testSpy() {
    spyList.add("one");
    spyList.add("two");

    // 在spy对象上设定返回预期值
    Mockito.doReturn(100).when(spyList).size();

    assertEquals(100, spyList.size());
    assertEquals("one", spyList.get(0));
}

1.3  @mockbean与@SpyBean

@MockBean 和 @SpyBean 是 Spring Boot 测试中常用的两个注解。下面是它们各自的特性:

  1. @MockBean

    • @MockBean 用于在 Spring 上下文中创建一个 Mock 对象,用它替换任何同类型的原有 Bean。
    • @MockBean 创建的mock对象没有任何实际行为,只返回预设的值。
    • 使用 @MockBean,你可以设置对其进行调用的各个方法的预期返回值。
  2. @SpyBean

    • @SpyBean 用于在 Spring 上下文中创建一个 Spy 对象,用它替换任何同类型的原有的 Bean。
    • @SpyBean 创建的 spy 对象基于实际的 Bean,事实上它就是原有 Bean 的一个复制体。除非明确地设定,否则它的方法调用结果与原有 Bean 完全相同。
    • 使用 @SpyBean,你可以监视(或跟踪)Bean 的行为,并能在需要时们改变某些方法的行为。

总的来说,@MockBean 和 @SpyBean 的核心区别是:@MockBean 创建的是一个可配置的纯 mock 对象,而 @SpyBean 则是基于一个实际对象的副本,这个副本中的方法调用能够反映出原有对象的行为。

使用场景:

@MockBean使用场景和代码示例

使用场景:我们通常在Spring的集成测试中使用@MockBean,这个注解用于替换Spring应用程序上下文中的现有Bean。它创建了一个Mock实例,并使用它替换原本的Bean。

@SpyBean使用场景和代码示例

使用场景:当我们希望监测真实的Bean时,我们使用@SpyBean。一个 Spy Bean 是一个代理,在这个代理中,被Spy的Bean的所有方法都会像平常一样被调用,除非我们明确地改变它们的行为。

 1.4 verify的使用方法及场景

Mockito.verify() 方法是 Mockito 框架中用于验证 mock 对象方法调用的工具。通过 verify() 方法,我们可以检查 mock 对象的某个方法是否被调用了,并可以进一步验证调用次数、调用顺序、传入参数等情况。

下面是 Mockito.verify() 方法的基本使用方法及一些常见应用场景:

验证方法是否被调用:

// 创建 mock 对象
List<String> mockList = Mockito.mock(List.class);

// 调用被测试的方法
mockList.add("test");

// 验证方法 add 是否被调用过一次
Mockito.verify(mockList).add("test");

这两个方法里面的参数必须一样才能进行验证。如果你要验证的方法参数与实际调用的方法参数不一样,那么 Mockito.verify() 方法会抛出异常并提示参数不匹配。

 验证方法被调用次数:

// 验证方法 add 被调用了两次
Mockito.verify(mockList, Mockito.times(2)).add("test");

 验证方法未被调用:

// 验证方法 add 未被调用
Mockito.verify(mockList, Mockito.never()).add("test");

 验证方法在特定顺序下被调用:

// 模拟方法调用
InOrder inOrder = Mockito.inOrder(mockList);
inOrder.verify(mockList).add("first");
inOrder.verify(mockList).add("second");

 验证方法传入参数:

// 验证方法 add 是否被调用,并且传入参数为字符串 "hello"
Mockito.verify(mockList).add(Mockito.eq("hello"));

 验证方法在特定时间内被调用:

// 验证方法 add 在100ms内是否被调用
Mockito.verify(mockList, Mockito.timeout(100)).add("test");

二、Junit5注解及断言

2.1 Junit5内置注解

2.2 junit5内置断言

三、Mockito 和 PowerMock的差异对比

Mockito 和 PowerMock 是两种广泛使用的 Java 单元测试模拟框架。它们都提供了创建和管理 mock 对象的能力,以帮助我们隔离并测试代码。然而,它们各自的特性使得它们在特定的场景中更有效。

Mockito 特性:

  1. 是目前最流行的 mocking 框架。
  2. 它能实现对方法的调用进行模拟,并验证方法的调用情况,通过一种优雅且简洁的 API 来提供这种功能。
  3. Mockito 不支持 mock 私有,静态和 fianl 方法或类的模拟
  4. Mockito 的语法简单且易于阅读,代码可维护性更高。
  5. Mockito 更关注于“测试行为”,而非“测试结果”。

PowerMock 特性:

  1. PowerMock 是 Mockito 和 EasyMock 的扩展,它能够模拟更加复杂的场景,包括静态方法,构造器,final 类及方法,私有方法等。
  2. PowerMock 使用字节码操作技术,通过在运行时修改字节码的方式实现这些复杂的模拟。
  3. PowerMock 能够执行更深层次的测试,但复杂的特性可能导致代码难以阅读和维护。
  4. PowerMock 适合用来模拟那些传统上被视为不可模拟的代码。

两者的主要使用场景:

  • Mockito 适合用于大多数标准的模拟情况,可以覆盖大部分的日常测试需求。其简单、易读的 API 使其成为首选工具。
  • PowerMock 的使用场景则更为具体,如必须模拟静态方法、final 类/方法或私有方法等情况。不过使用 PowerMock 应慎重,这些能力常常提示代码设计存在问题。

 使用powerMock模拟mock静态方法

public class UtilityClass {
    static int staticMethod(long value) {
        return 100;
    }
}

@RunWith(PowerMockRunner.class)
@PrepareForTest(UtilityClass.class)
public class MockingStaticMethodTest {

    @Test
    public void testMockingStaticMethod() {

        //模拟整个 UtilityClass 类
        PowerMockito.mockStatic(UtilityClass.class);

        //设置预期返回
        PowerMockito.when(UtilityClass.staticMethod(5)).thenReturn(10);

        //在你的测试代码里, 当 UtilityClass.staticMethod(5) 被调用时, 它现在将返回 10
        int result = UtilityClass.staticMethod(5);

        assertEquals(10, result);

        //最后验证静态方法是否被调用
        PowerMockito.verifyStatic(UtilityClass.class);
        UtilityClass.staticMethod(5);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/541780.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SQL语言自用(持续更新)+实验记录

课本:《数据库原理及其应用教程》&#xff08;第四版&#xff09; (主编)黄德才&(副主编)陆亿红 实验&#xff1a;学校实验课材料 其他&#xff1a; [ ]表示可以被删除&#xff0c;也表示可以被替换&#xff0c;请自行判断。如果有一些截图或照片&#xff0c;是暂时懒得整…

基于SpringBoot的“滴答拍摄影项目”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“滴答拍摄影项目”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 滴答拍摄影项目结构图 管理员登录首页界面图 用…

[lesson24]经典问题解析二

经典问题解析二 关于析构的疑问 当程序中存在多个对象的时候&#xff0c;如何确定这些对象的析构顺序&#xff1f;单个对象创建时构造函数的调用顺序 1.调用父类的构造过程2.调用成员变量的构造函数(调用顺序于声明顺序相同)调用类自身的构造函数 析构函数与对应的构造函数的…

车联网大数据与人工智能一体化:开启智慧出行新时代

随着物联网技术的快速发展&#xff0c;车联网已经成为了汽车行业的重要趋势之一。而在车联网的发展过程中&#xff0c;大数据和人工智能的应用也日益成为关键因素。本文将探讨如何将大数据与人工智能一体化应用于车联网&#xff0c;以实现智慧出行的目标。 尤其是近来国内的华为…

【算法刷题 | 回溯思想 03】4.13( 组合总和、组合总和|| )

文章目录 5.组合总和5.1题目5.2解法&#xff1a;回溯5.2.1回溯思路&#xff08;1&#xff09;函数返回值以及参数&#xff08;2&#xff09;终止条件&#xff08;3&#xff09;遍历过程 5.2.2代码实现 6.组合总和 ||6.1题目6.2解法&#xff1a;回溯6.2.1回溯思路&#xff08;1&…

Linux软件包管理器yum—5

一、Linux下软件安装的方式 ①源代码安装&#xff1a; ②rmp包安装&#xff1a; 本质是拷贝可执行程序到系统目录下。 ③yum一键下载&#xff0c;安装&#xff0c;卸载。相当于手机的应用商店。 二、yum 2.1查看yum已配置的源&#xff1a; ls /etc/yum.repos.d/ 2.2查看yum…

Nexus 启动异常

在迁移 Nexus 到新的服务器上&#xff0c;我们有下面的异常。 [rootdevops log]# /opt/nexus/bin/nexus start No suitable Java Virtual Machine could be found on your system. The version of the JVM must be 1.8. Please define INSTALL4J_JAVA_HOME to point to a suita…

springboot数字化智慧城市管理系统源码

目录 ​系统开发环境 系统功能模块 系统特点 1、智慧城管移动端 2、案件受理 3、AI视频智识别分析 系统应用价值 1、提升案件办理效率 2、提升监管效能 3、提升行政执法水平 4、推进行政执法创新 智慧城管综合执法办案系统功能 现场移动执法 一般程序案件的网上办…

5.3 mybatis之autoMappingUnknownColumnBehavior作用

文章目录 1. NONE2. WARNING3. FAILING autoMappingUnknownColumnBehavior是< settings >配置下的属性&#xff0c;该属性是指定发现自动映射目标未知列&#xff08;或未知属性类型&#xff09;的行为。就是说当数据库中的字段找不到映射java对象的属性或者与java对象对应…

MQ概览及Kafka详解

文章目录 概览MQ优点MQ缺点常见MQ对比JMS消息模型点对点模式发布订阅模式 kafka基础架构发布订阅工作流程生产者生产者文件存储生产者分区策略生产者数据可靠性保证生产者数据一致性保证生产者ack机制ExactlyOnce生产者发送消息流程 消费者消费者分区分配策略消费者消费数据问题…

MATLAB 自定义实现点云法向量和曲率计算(详细解读)(64)

MATLAB 自定义实现点云法向量和曲率计算(详细解读)(64) 一、算法介绍二、算法步骤三、算法实现1.代码 (完整,注释清晰,可直接用)2.结果一、算法介绍 首先说明: ------这里代码手动实现,不调用matlab提供的法向量计算接口,更有助于大家了解法向量和曲率的计算方法,…

Docker 学习笔记(八):Dockerfile实战篇,制作 Tomcat 镜像,发布镜像到 DockerHub 和阿里云

一、前言 记录时间 [2024-4-13] 系列文章简摘&#xff1a; Docker 学习笔记&#xff08;六&#xff09;&#xff1a;挑战容器数据卷技术一文通&#xff0c;实战多个 MySQL 数据同步&#xff0c;能懂会用&#xff0c;初学必备 Docker 学习笔记&#xff08;七&#xff09;&#x…

数据结构——基于单链表实现通讯管理系统

文章目录 一、前言SList.hSList.c 二、通讯录的实现通讯录项目Contact.h载入数据初始化通讯录添加通讯录数据通过姓名查找联系人删除通讯录数据展示通讯录数据查找通讯录数据修改通讯录数据保存通讯录销毁通讯录数据 三、所有源代码Contact.hContact.cSList.hSList.ctest.c 一、…

Sonar+postsql的安装配置,centos7.9系统

1.安装postsql15 sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-6-x86_64/pgdg-redhat-repo-latest.noarch.rpm sudo yum install -y postgresql15-server sudo service postgresql-15 initdb sudo chkconfig postgresql-15 on sudo servic…

[StartingPoint][Tier2]Included

LXD https://www.hackingarticles.in/lxd-privilege-escalation/ Task 1 What service is running on the target machine over UDP? &#xff08;目标机器上通过UDP运行的服务是什么&#xff1f;&#xff09; $ nmap -sU 10.129.232.86 -p 69 tftp Task 2 What class o…

每日一博 - 重新定义JAR中的类或方法

文章目录 概述方式一 &#xff1a; 项目覆写相同包结构的类方式二&#xff1a; 魔改Jar包中的类方案对比方案一&#xff1a;在项目中新增第三方包路径方案二&#xff1a;替换JAR包中的类文件 概述 在一些情况下&#xff0c;我们可能需要定制第三方库的行为&#xff0c;但却无法…

部署HDFS集群(完全分布式模式、hadoop用户控制集群、hadoop-3.3.4+安装包)

目录 前置 一、上传&解压 &#xff08;一 &#xff09;上传 &#xff08;二&#xff09;解压 二、修改配置文件 &#xff08;一&#xff09;配置workers文件 &#xff08;二&#xff09;配置hadoop-env.sh文件 &#xff08;三&#xff09;配置core-site.xml文件 &…

人工智能|机器学习——基于机器学习的信用卡办卡意愿模型预测项目

一、背景介绍 在金融领域&#xff0c;了解客户的信用卡办卡意愿对于银行和金融机构至关重要。借助机器学习技术&#xff0c;我们可以根据客户的历史数据和行为模式预测其是否有办理信用卡的倾向。本项目通过Python中的机器学习库&#xff0c;构建了两个常用的分类模型&#xff…

自定义创建真实项目vue2项目

1. 创建 vue create 项目名 2. 选择自定义 3. 勾选以下必备选项 4.选择使用vue2 5. 选择哈希模式&#xff08;n&#xff09;; css选择Less 6. ESLint校验 选择 7. 保存&#xff08;按照默认&#xff09; 8. 在哪里添加ESLint文件 9. 要不要把这个改成将来的预设&am…

底层开发必知的三个内存结构概念

大家好&#xff0c;今天给大家介绍底层开发必知的三个内存结构概念&#xff0c;文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 在底层开发中&#xff0c;以下是三个关键的内存结构概念&…