Java 单元测试模拟框架-Mockito 的介绍

Mockito 是什么

在这里插入图片描述

Mockito 是一个用于单元测试的模拟框架,基于它可以使用简洁易用的API编写出色的测试。
Mockito 允许开发人员创建和管理模拟对象(mock objects),以便在测试过程中替换那些不容易构造或获取的对象。

Mockito的基本概念

  1. Mock对象:在调试期间用来作为真实对象的替代品。通过模拟对象,可以模拟外部依赖、交互行为等,从而使测试更加独立和可控。
  2. Mock测试:在测试过程中,对那些不容易构建的对象用一个虚拟对象来代替测试的方法就叫mock测试。
  3. Stub:存根,即为mock对象的方法指定返回值(可抛出异常)。
  4. Verify:行为验证,验证指定方法调用情况(是否被调用,调用次数等)。

Mockito的主要功能

  1. 模拟方法行为:Mockito允许对模拟对象的方法进行stubbing,即定义当调用某个方法时应该返回的值或抛出的异常。
  2. 验证交互行为:Mockito提供了丰富的API来验证模拟对象的交互行为,例如方法是否被调用、调用次数、参数匹配等。
  3. 参数匹配器:Mockito提供了参数匹配器,允许在验证方法调用时使用通配符或自定义匹配规则。
  4. 部分模拟:使用@Spy注解可以创建一个部分模拟对象,允许选择性地模拟对象中的某些方法。

选择Mockito作为模拟框架的原因

  • StackOverflow庞大的社区将Mockito评为Java的最佳模拟框架
  • 在2013年末对30,000个GitHub项目进行分析时,Mockito在所有库(不仅仅是测试工具)中位列前10名Java库。尽管Mockito在主报告中排名第九,但mockito-core和mockito-all是同一工具,因此Mockito的实际排名是第四,超过了诸如Guava或Spring等著名工具。将此研究视为Mockito每天对用Java编写的单元测试产生巨大影响的指标。
  • 行为驱动开发(BDD)的创始人Dan North在2008年写道:“我们在主要会议期间决定使用JUnit 4和Mockito,因为我们认为它们是Java中TDD和模拟的未来。”

基于Maven 如何使用Mockito:

Mockito的使用步骤

  1. 添加依赖:在项目的构建文件(如Maven的pom.xml或Gradle的build.gradle)中添加Mockito的依赖。
  2. 设置测试类:使用@RunWith(MockitoJUnitRunner.class)注解测试类,或使用MockitoAnnotations.initMocks(this)在@Before方法中初始化模拟对象。
  3. 创建模拟对象:使用@Mock注解创建模拟对象,或使用Mockito.mock(Class)方法。
  4. 设置模拟行为:使用when(…).thenReturn(…)或doReturn(…).when(…)等方法设置模拟对象的行为。
  5. 编写测试方法:在测试方法中调用被测对象的方法,并使用verify(…)等方法验证交互行为。
  6. 运行测试:使用JUnit运行测试,并查看测试结果。

Mockito当前的最新版本是 5.14.2,在pom.xml中导入之后就可以开始使用了。

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>5.14.2</version>
</dependency>

使用场景1: 验证交互行为, 模拟方法是否被调用了?

创建Mock对象, 验证对象的方法是否被调用了。

/**
 * Copyright (C)  Oscar Chen(XM):
 * 
 * Date: 2024-12-01
 * Author: XM
 */
package com.osxm.test.mock;

import static org.mockito.Mockito.*; // 导入Mockito的静态方法

import java.util.List;

import org.junit.jupiter.api.Test;

public class MockitoTest {

    @Test
    public void mockitoDemo() {

        // 创建mock对象
        List mockedList = mock(List.class); // 创建一个List接口的mock对象
        // 或者在Mockito 4.10.0及以上版本中,使用更简洁的方式
        // List mockedList = mock();

        // 使用mock对象,它不会抛出任何“意外交互”异常
        mockedList.add("one");
        mockedList.clear();

        // 选择性、明确且高度可读的验证
        verify(mockedList).add("one"); // 验证mock对象调用了add方法并传入了"one"
        verify(mockedList).clear(); // 验证mock对象调用了clear方法

    }

}

使用场景2:模拟方法调用

模拟方法执行返回的结果。

    @Test
    public void mockMethodCall(){
        // 不仅可以模拟接口,还可以模拟具体类
        LinkedList mockedList = mock(LinkedList.class); // 创建一个LinkedList类的mock对象
        // 或者在Mockito 4.10.0及以上版本中,使用更简洁的方式
        // LinkedList mockedList = mock();

        // 在实际执行之前进行模拟(stubbing)
        when(mockedList.get(0)).thenReturn("first"); // 当调用mockedList的get(0)方法时,返回"first"

        // 以下打印输出为"first"
        System.out.println(mockedList.get(0));

        // 以下打印输出为"null",因为get(999)方法没有被模拟
        System.out.println(mockedList.get(999));
    }

主要参考

  • mock()方法,或者 @Mock注解: 创建模拟对象
  • when()/given() 指定模拟对象的行为
  • spy()/@Spy 部门模拟, 真实方法会呼叫并且可以被验证和存根
  • @InjectMocks:自动注入用@Spy或@Mock注解的模拟/间谍字段
  • verify() : 检查方法是否使用给定参数被调用
    • 可以使用灵活的参数匹配,例如通过any()匹配任意表达式
    • 或者使用@Captor捕获被调用的参数
  • 可以使用BDDMockito进行行为驱动开发语法

Mockito的常用注解

  1. @RunWith:用于指定JUnit测试的运行器。对于Mockito,通常使用@RunWith(MockitoJUnitRunner.class)来运行测试。
  2. @Mock:用于创建模拟对象。
  3. @InjectMocks:用于将模拟对象注入到被测对象中。
  4. @Spy:用于创建部分模拟对象。

使用注意

不要干什么:

  • 不要模拟不属于你的类型
  • 不要模拟值对象
  • 不要模拟一切
  • 对测试表现一些爱心

不能干什么:

  1. 不能Mock静态方法:Mockito不支持对静态方法进行mock。
  2. 不能Mock private方法:Mockito不支持对private方法进行mock。
  3. 不能Mock final class:Mockito不支持对final类进行mock。

Mockito的集成与扩展

  1. 与JUnit集成:Mockito可以与JUnit无缝集成,使用@RunWith(MockitoJUnitRunner.class)即可。
  2. 与Spring集成:在Spring Boot项目中,可以使用@MockBean注解来模拟Spring上下文中的对象。
  3. 扩展功能:Mockito提供了丰富的扩展功能,如Mockito-inline用于支持内联Mocks的创建和使用等。

参考

  • 官方站点 http://site.mockito.org/#intro

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

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

相关文章

斯坦福李飞飞《AI Agent:多模态交互前沿调查》论文

多模态AI系统很可能会在我们的日常生活中无处不在。将这些系统具身化为物理和虚拟环境中的代理是一种有前途的方式&#xff0c;以使其更加互动化。目前&#xff0c;这些系统利用现有的基础模型作为构建具身代理的基本构件。将代理嵌入这样的环境中&#xff0c;有助于模型处理和…

shell语法(1)bash

shell是我们通过命令行与操作系统沟通的语言&#xff0c;是一种解释型语言 shell脚本可以直接在命令行中执行&#xff0c;也可以将一套逻辑组织成一个文件&#xff0c;方便复用 Linux系统中一般默认使用bash为脚本解释器 在Linux中创建一个.sh文件&#xff0c;例如vim test.sh…

十六(AJAX3)、XMLHttpRequest、Promise、简易axios封装、案例天气预报、lodash-debounce防抖

1. XMLHttpRequest 1.1 XMLHttpRequest-基本使用 /* 定义&#xff1a;XMLHttpRequest&#xff08;XHR&#xff09;对象用于与服务器交互。通过 XMLHttpRequest 可以在不刷新页面的情况下请求特定 URL&#xff0c;获取数据。这允许网页在不影响用户操作的情况下&#xff0c;更…

AI效率手册学习笔记

目录 概要 主流的AI工具 提示词工程 概要 多一个工具&#xff0c;就意味着我们多一个助手&#xff0c;多一个信息源渠道&#xff0c;也就相当于多一份帮助。 学习书籍&#xff1a;《AI效率手册&#xff1a;从ChatGPT开启高效能》常青 著 出版时间&#xff1a;2024-10-01 主…

瑞芯微RK3566/RK3568开发板安卓11固件ROOT教程,Purple Pi OH演示

本文介绍RK3566/RK3568开发板Android11系统&#xff0c;编译ROOT权限固件的方法。触觉智能Purple Pi OH鸿蒙开发板演示&#xff0c;搭载了瑞芯微RK3566四核处理器&#xff0c;Laval鸿蒙社区推荐开发板&#xff0c;已适配全新OpenHarmony5.0 Release系统&#xff0c;SDK源码全开…

【Linux】线程概念 | 线程控制

文章目录 &#x1f449;知识补充&#x1f448;&#x1f449;Linux线程概念&#x1f448;什么是线程Makefile线程 VS 进程线程的优点线程的缺点线程异常线程用途 &#x1f449;线程控制&#x1f448;线程终止pthread_exit 函数pthread_cancel 函数线程 ID 的深入理解在多线程的场…

LongVU:用于长视频语言理解的空间时间自适应压缩

晚上闲暇时间看到一种用于长视频语言理解的空间时间自适应压缩机制的研究工作LongVU&#xff0c;主要内容包括&#xff1a; 背景与挑战&#xff1a;多模态大语言模型&#xff08;MLLMs&#xff09;在视频理解和分析方面取得了进展&#xff0c;但处理长视频仍受限于LLM的上下文长…

爬虫项目基础知识详解

文章目录 Python爬虫项目基础知识一、爬虫与数据分析1.1 Python中的requests库Requests 库的安装Requests 库的 get() 方法爬取网页的通用代码框架HTTP 协议及 Requests 库方法Requests 库主要方法解析 1.2 python中的json库1.3 xpath学习之python中lxml库html了解html结构html…

LeetCode - #152 乘积最大子数组(Top 100)

文章目录 前言1. 描述2. 示例3. 答案关于我们 前言 本题为 LeetCode 前 100 高频题 我们社区陆续会将顾毅&#xff08;Netflix 增长黑客&#xff0c;《iOS 面试之道》作者&#xff0c;ACE 职业健身教练。&#xff09;的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 …

记一次跑前端老项目的问题

记一次跑前端老项目的问题 一、前言二、过程1、下载依赖2、启动项目3、打包 一、前言 在一次跑前端老项目的时候&#xff0c;遇到了一些坑&#xff0c;这里记录一下。 二、过程 1、下载依赖 使用 npm install下载很久&#xff0c;然后给我报了个错 core-js2.6.12: core-js…

无约束最优化问题的求解算法

无约束最优化问题的求解算法 使用梯度下降法目的和原因 目的 梯度下降法(Gradient Descent)是一个算法&#xff0c;但不是像多元线性回归那样是一个具体做回归任务的算法&#xff0c;而是一个非常通用的优化算法来帮助一些机器学习算法求解出最优解的&#xff0c;所谓的通用就是…

VideoBooth: Diffusion-based Video Generation with Image Prompts

VideoBooth: Diffusion-based Video Generation with Image Prompts 概括 文章提出了一个视频生成模型VideoBooth&#xff0c;输入一张图片和一个文本提示词&#xff0c;即可输出保持图片中物体且符合文本提示词要求的视频。 方法 粗-细两阶段设计&#xff1a;1&#xff09;…

AndroidAutoSize实战教程:今日头条屏幕适配方案详解

如何在项目中结合 AndroidAutoSize 来进行今日头条屏幕适配&#xff0c;我会具体讲解如何用 AndroidAutoSize 实现屏幕适配&#xff0c;并结合 Kotlin 代码举例分析。 通过 AndroidAutoSize 库来实现屏幕适配&#xff0c;确保在不同的屏幕尺寸、分辨率、密度下&#xff0c;应用…

为什么使用3DMAX插件会出现系统崩溃?

使用3DMAX插件时出现系统崩溃&#xff0c;可能涉及多个方面的原因。以下是一些主要的原因及相应的解决方案&#xff1a; 一、插件兼容性问题 版本不兼容&#xff1a; 旧版插件可能无法与最新版本的3DMAX完全兼容&#xff0c;导致系统崩溃。解决方案&#xff1a;更新插件至最新…

[pdf,epub]228页《分析模式》漫谈合集01-45提供下载

《分析模式》漫谈合集01-45的pdf、epub文件提供下载。已上传至本号的CSDN资源。 如果CSDN资源下载有问题&#xff0c;可到umlchina.com/url/ap.html。 已排版成适合手机阅读&#xff0c;pdf的排版更好一些。 ★UMLChina为什么叒要翻译《分析模式》&#xff1f; ★[缝合故事]…

Python 【图像分类】之 PyTorch 进行猫狗分类功能的实现(Swanlab训练可视化/ Gradio 实现猫狗分类 Demo)

Python 【图像分类】之 PyTorch 进行猫狗分类功能的实现(Swanlab训练可视化/ Gradio 实现猫狗分类 Demo) 目录 Python 【图像分类】之 PyTorch 进行猫狗分类功能的实现(Swanlab训练可视化/ Gradio 实现猫狗分类 Demo) 一、简单介绍 二、PyTorch 三、CNN 1、神经网络 2、卷…

HarmonyOS开发:关于签名信息配置详解

目录 前言 签名信息的重要性 签名的方式 自动化签名 1、连接真机 2、选择 手动签名 &#xff08;一&#xff09;生成密钥和证书请求文件 &#xff08;二&#xff09;申请调试证书 &#xff08;三&#xff09;注册调试设备 &#xff08;四&#xff09;申请调试Profil…

Java的Stirng、StringBuilder、StringJoiner

黑马程序员Java个人笔记 目录 字符串比较 比较 boolean equals boolean equalsIgnoreCase 键盘录入和定义的字符串的比较 StringBuilder 打印 ​编辑 添加元素 反转 获取长度 toString 练习 对称字符串 拼接字符串 StringJoiner 概述 ​编辑 构造方法 只有…

fastadmin 后台插件制作方法

目录 一&#xff1a;开发流程 二&#xff1a;开发过程 &#xff08;一&#xff09;&#xff1a;后台功能开发 &#xff08;二&#xff09;&#xff1a;功能打包到插件目录 &#xff08;三&#xff09;&#xff1a;打包插件 &#xff08;四&#xff09;&#xff1a;安装插件…

视频自学笔记

一、视频技术基本框架 二、视频信号分类 2.1信号形式 2.1.1模拟视频 模拟视频是指由连续的模拟信号组成的视频图像&#xff0c;以前所接触的电影、电视都是模拟信号&#xff0c;之所以将它们称为模拟信号&#xff0c;是因为它们模拟了表示声音、图像信息的物理量。摄像机是获…