首页 > 其他分享 >单元测试 - Mockito - 1

单元测试 - Mockito - 1

时间:2023-12-16 10:33:07浏览次数:37  
标签:random 对象 Mockito 单元测试 StaticUtils class mock

1. 为什么要使用 mock

Mock 可以理解为创建一个虚假的对象,或者说模拟出一个对象,在测试环境中用来替换掉真实的对象,以达到我们可以:

  • 验证该对象的某些方法的调用情况,调用了多少次,参数是多少
  • 给这个对象的行为做一个定义,来指定返回结果或者指定特定的动作

2. Mockito 中常用方法

2.1 Mock 方法

mock 方法来自 org.mockito.Mock,它表示可以 mock 一个对象或者是接口。

public static <T> T mock(Class<T> classToMock)
  • classToMock:待 mock 对象的 class 类。
  • 返回 mock 出来的类

实例:使用 mock 方法 mock 一个类

Random random = Mockito.mock(Random.class);

2.2 对 Mock 出来的对象进行行为验证和结果断言

验证是校验待验证的对象是否发生过某些行为,Mockito 中验证的方法是:verify。

verify(mock).someMethod("some arg");
verify(mock, times(1)).someMethod("some arg");

使用 verify 验证:

Verify 配合 time() 方法,可以校验某些操作发生的次数。

@Test
void check() {
    Random random = Mockito.mock(Random.class, "test");
    System.out.println(random.nextInt());
    Mockito.verify(random,Mockito.times(2)).nextInt();
}

断言使用到的类是 Assertions.

Random random = Mockito.mock(Random.class, "test");
Assertions.assertEquals(100, random.nextInt());

输出结果:

org.opentest4j.AssertionFailedError: 
Expected :100
Actual   :0

当使用 mock 对象时,如果不对其行为进行定义,则 mock 对象方法的返回值为返回类型的默认值。

2.3 给 Mock 对象打桩

打桩可以理解为 mock 对象规定一行的行为,使其按照我们的要求来执行具体的操作。在 Mockito 中,常用的打桩方法为

方法 含义
when().thenReturn() Mock 对象在触发指定行为后返回指定值
when().thenThrow() Mock 对象在触发指定行为后抛出指定异常
when().doCallRealMethod() Mock 对象在触发指定行为后调用真实的方法

thenReturn() 代码示例

@Test
void check() {
    Random random = Mockito.mock(Random.class, "test");
    Mockito.when(random.nextInt()).thenReturn(100);
    Assertions.assertEquals(100, random.nextInt());
}
测试通过

2.4 Mock 静态方法

首先要引入 Mockito-Inline 的依赖。

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-inline</artifactId>
    <version>4.3.1</version>
    <scope>test</scope>
</dependency>

使用 mockStatic() 方法来 mock静态方法的所属类,此方法返回一个具有作用域的模拟对象。

@Test
void range() {
    MockedStatic<StaticUtils> utilities = Mockito.mockStatic(StaticUtils.class);
    utilities.when(() -> StaticUtils.range(2, 6)).thenReturn(Arrays.asList(10, 11, 12));
    Assertions.assertTrue(StaticUtils.range(2, 6).contains(10));
}
@Test
void name() {
    MockedStatic<StaticUtils> utilities = Mockito.mockStatic(StaticUtils.class);
    utilities.when(StaticUtils::name).thenReturn("bilibili");
    Assertions.assertEquals("1", StaticUtils.	name());
}

执行整个测试类后会报错:

org.mockito.exceptions.base.MockitoException: 
For com.echo.mockito.Util.StaticUtils, static mocking is already registered in the current thread

To create a new mock, the existing static mock registration must be deregistered

原因是因为 mockStatic() 方法是将当前需要 mock 的类注册到本地线程上(ThreadLocal),而这个注册在一次 mock 使用完之后是不会消失的,需要我们手动的去销毁。如过没有销毁,再次 mock 这个类的时候 Mockito 将会提示我们 :”当前对象 mock 的对象已经在线程中注册了,请先撤销注册后再试“。这样做的目的也是为了保证模拟出来的对象之间是相互隔离的,保证同时和连续的测试不会收到上下文的影响。

因此修改代码:

class StaticUtilsTest {

    @Test
    void range() {
        try (MockedStatic<StaticUtils> utilities = Mockito.mockStatic(StaticUtils.class)) {
            utilities.when(() -> StaticUtils.range(2, 6)).thenReturn(Arrays.asList(10, 11, 12));
            Assertions.assertTrue(StaticUtils.range(2, 6).contains(10));
        }

    }

    @Test
    void name() {
        try (MockedStatic<StaticUtils> utilities = Mockito.mockStatic(StaticUtils.class)) {
            utilities.when(StaticUtils::name).thenReturn("bilibili");
            Assertions.assertEquals("bilibili", StaticUtils.name());
        }
    }
}

标签:random,对象,Mockito,单元测试,StaticUtils,class,mock
From: https://www.cnblogs.com/otf-notes/p/17904570.html

相关文章

  • 【转载】Springboot2.x单元测试
    参考https://blog.csdn.net/wangxi06/article/details/114630426https://blog.csdn.net/qq_44381387/article/details/120869168(新版spring-boot-starter-test不再集成junit,而是junit-jupiter,无需@RunWith)https://www.jianshu.com/p/34f57f41af70https://www.cnblogs.co......
  • 【转载】SpringBoot2.x使用Assert校验(非单元测试)
    参考https://blog.csdn.net/yangshangwei/article/details/123105926环境环境版本操作windows10JDK11Springboot2.3.12.RELEASE注意引入的包为importorg.springframework.util.Assert;介绍对象和类型断言函数说明notNull()假设对......
  • vitest&@vue/test-utils组件单元测试
    依赖"vitest":"0.34.6","@vue/test-utils":"2.4.3","axios-mock-adapter":"^1.22.0",示例import{mount}from"@vue/test-utils";import{test,vi}from"vitest";import{gl......
  • iOS单元测试
    一、简介单元测试通常由软件开发人员自己编写,他们将确认具体功能是否按照设计要求正常工作。单元测试的目标是隔离代码的每个部分,并确保每个独立的部分都能正常工作。例如,如果你有一个计算器应用程序,你可能会为加法、减法、乘法和除法等每个功能编写单元测试,以确保当给定特定输入时......
  • 单元测试实战(二)Service 的测试
    单元测试实战(二)Service的测试为鼓励单元测试,特分门别类示例各种组件的测试代码并进行解说,供开发人员参考。本文中的测试均基于JUnit5。单元测试实战(一)Controller的测试单元测试实战(二)Service的测试单元测试实战(三)JPA的测试  单元测试实战(四)MyBatis-Plus的测试单......
  • Java编写单元测试用例
    Java编写单元测试用例01简介Java中可以使用多个测试框架来执行单元测试,其中最流行的测试框架之一是JUnit。下面是一个简单的示例,说明如何使用JUnit框架编写和执行单元测试:02一、JUnit包导入importorg.junit.*;03二、创建测试类这个类需要使用“@RunWith’和@Suite”注......
  • Java单元测试浅析(JUnit+Mockito)
    Java单元测试浅析(JUnit+Mockito)作者:京东物流秦彪1.什么是单元测试(1)单元测试环节:测试过程按照阶段划分分为:单元测试、集成测试、系统测试、验收测试等。相关含义如下:1)单元测试:针对计算机程序模块进行输出正确性检验工作。2)集成测试:在单元测试基础上,整合各个模......
  • Mockito When/Then常见用法
    MockitoWhen/Then常见用法该系列文章翻译自https://www.baeldung.com/mockito-series接下来我们将以MyList类为例进行介绍publicclassMyListextendsAbstractList<String>{@OverridepublicStringget(finalintindex){returnnull;}@Over......
  • java 单元测试之 - Spring框架提供的单元/集成测试注解
    java单元测试之-Spring框架提供的单元/集成测试注解Spring框架提供了很多注解来辅助完成单元测试和集成测试(备注:这里的集成测试指容器内部的集成测试,非系统间的集成测试),先看看Spring框架提供了哪些注解以及对应的作用。@RunWith(SpringRunner.class)/@ExtendWith(Spring......
  • Java Mockito 快速入门指南 Mock是指使用Mockito创建的模拟对象,它模拟真实对象的行为,
    JavaMockito快速入门指南Mock是指使用Mockito创建的模拟对象,它模拟真实对象的行为,用于替代真实对象的依赖项,以便进行独立的单元测试在软件开发中,单元测试对于确保代码的正确性和可靠性至关重要。Mockito是一个强大的Java测试框架,它提供了丰富的功能和方法,使得编写模拟测试变得......