Mockito的简单使用

基本介绍

什么是 Mock 测试

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

Mock 最大的功能是帮你把单元测试的耦合分解开,如果你的代码对另一个类或者接口有依赖,它能够帮你模拟这些依赖,并帮你验证所调用的依赖的行为。

比如一段代码有这样的依赖:
在这里插入图片描述
当我们需要测试A类的时候,如果没有 Mock,则我们需要把整个依赖树都构建出来,而使用 Mock 的话就可以将结构分解开,像下面这样:
在这里插入图片描述

在哪里使用Mock对象?

  • 真实对象很难被创建的
  • 真实对象的某些行为很难被触发
  • 真实对象实际上还不存在的(正在开发中)等等

一、添加依赖

        <!--mockito框架-->
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>3.5.15</version>
            <scope>test</scope>
        </dependency>

如果在导包时报错,删掉上面的scope作用域标签

1.验证行为

    @Test
    public void test1() {

        // 可以模拟一个接口
        List mockedList = mock(List.class);

        // 然后可以直接使用接口的方法
        mockedList.add("one");
        mockedList.clear();

        //verification  验证是否发生某种行为,发生了,啥都不做,未发生,报错
        // 下面这句会报错,因为 add的是one而不是two
        // verify(mockedList).add("two");

        verify(mockedList).clear();
    }

2.模拟一个实体类

    @Test
    public void test2() {

        // mock一个具体的类,产生mock后的对象
        LinkedList mockedList = mock(LinkedList.class);


        when(mockedList.get(0)).thenReturn("first");
        when(mockedList.get(1)).thenThrow(new RuntimeException("我自己抛出的异常"));

        // following prints "first"
        System.out.println(mockedList.get(0));

        // following throws runtime exception
        // System.out.println(mockedList.get(1));

        // null 因为没有存过999
        System.out.println(mockedList.get(999));

        mockedList.add("11111");

        // 猜想:因为不是真实对象,所以size()始终为 0
        System.out.println(mockedList.size());

        // 验证调用了get(0)
        verify(mockedList).get(0);

    }

3.参数匹配器

    @Test
    public void test3() {

        // mock一个具体的类,产生mock后的对象
        LinkedList mockedList = mock(LinkedList.class);

        //stubbing using built-in anyInt() argument matcher
        when(mockedList.get(anyInt())).thenReturn("element");

        when(mockedList.contains(argThat(new Matches("ssss")))).thenReturn(true);
        // 可以使用正则表达式,没搞清楚怎么用的,下面返回true
        System.out.println(mockedList.contains("ssss"));


        //following prints "element"
        System.out.println(mockedList.get(999));

        //you can also verify using an argument matcher
        verify(mockedList).get(anyInt());
    }

4.验证方法调用的次数

    @Test
    public void test4() {

        // mock一个具体的类,产生mock后的对象
        LinkedList mockedList = mock(LinkedList.class);

        mockedList.add("once");
        mockedList.add("twice");
        mockedList.add("twice");

        mockedList.add("three times");
        mockedList.add("three times");
        mockedList.add("three times");

        //following two verifications work exactly the same - times(1) is used by default
        verify(mockedList).add("once");
        verify(mockedList, times(1)).add("once");

        //exact number of invocations verification
        verify(mockedList, times(2)).add("twice");
        verify(mockedList, times(3)).add("three times");

        //verification using never(). never() is an alias to times(0)
        verify(mockedList, never()).add("never happened");

        // 验证最少、最多调用的次数
        verify(mockedList, atLeastOnce()).add("three times");


        // verify(mockedList, atLeast(2)).add("five times");

        verify(mockedList, atMost(5)).add("three times");
    }

5.模拟方法抛出异常

    @Test
    public void test5() {

        // mock一个具体的类,产生mock后的对象
        LinkedList mockedList = mock(LinkedList.class);

        doThrow(new RuntimeException("我就抛出异常了")).when(mockedList).clear();

        //调用的时候就会抛出异常
        mockedList.clear();
    }

6.验证方法调用的顺序

    @Test
    public void test6() {

        // A. Single mock whose methods must be invoked in a particular order
        List singleMock = mock(List.class);

        //using a single mock
        singleMock.add("was added first");
        singleMock.add("was added second");

        //create an inOrder verifier for a single mock
        InOrder inOrder = inOrder(singleMock);

        // 验证方法调用的顺序, 如果下面列出的顺序和调用的顺序一样,则通过,否则抛出异常
        inOrder.verify(singleMock).add("was added first");
        inOrder.verify(singleMock).add("was added second");


        // B. Multiple mocks that must be used in a particular order
        List firstMock = mock(List.class);
        List secondMock = mock(List.class);

        //using mocks
        firstMock.add("was called first");
        secondMock.add("was called second");

        //create inOrder object passing any mocks that need to be verified in order
        InOrder inOrder2 = inOrder(firstMock, secondMock);

        //following will make sure that firstMock was called before secondMock
        inOrder2.verify(firstMock).add("was called first");
        inOrder2.verify(secondMock).add("was called second");
    }

7.确保 mock 上不会发生交互

    @Test
    public void test7() {

        List mockOne = Mockito.mock(List.class);
        List mockTwo = Mockito.mock(List.class);
        List mockThree = Mockito.mock(List.class);

        // using mocks - only mockOne is interacted
        mockOne.add("one");

        verify(mockOne).add("one");

        // 验证没有调用过某个行为
        verify(mockOne, never()).add("two");

        // 验证两个mock之间没有发生交互
        verifyZeroInteractions(mockTwo, mockThree);
    }
Mockito 是一个 Java 测试框架,用于模拟(mock)依赖项并使测试代码更简单和可读。它可以帮助您快速创建假的对象和模拟方法的行为。以下是 Mockito使用教程和示例。 ### 安装 Mockito使用 Mockito 之前,您需要将其添加到您的项目中。如果您使用 Maven,则可以将以下依赖项添加到您的 pom.xml 文件中: ```xml <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>3.3.3</version> <scope>test</scope> </dependency> ``` 如果您使用 Gradle,则可以将以下依赖项添加到您的 build.gradle 文件中: ``` testImplementation 'org.mockito:mockito-core:3.3.3' ``` ### 创建 Mock 对象 要创建 Mock 对象,您可以使用 Mockito 的 `Mockito.mock()` 方法。该方法接受一个 Class 类型的参数,并返回一个空的 Mock 对象。例如,要为一个名为 `UserService` 的类创建 Mock 对象,您可以编写以下代码: ```java UserService userService = Mockito.mock(UserService.class); ``` ### 设置 Mock 对象的行为 创建 Mock 对象之后,您可以使用 Mockito 的 `when()` 方法设置 Mock 对象的行为。该方法接受一个方法调用,并返回一个 `Mockito.when()` 对象,您可以使用该对象设置方法调用的返回值。例如,要设置 `UserService` 类的 `getUserById()` 方法调用返回一个名为 `John` 的用户,您可以编写以下代码: ```java User john = new User("John"); when(userService.getUserById(1)).thenReturn(john); ``` ### 验证 Mock 对象的方法调用 Mockito 还提供了一种验证 Mock 对象的方法调用的方法。要验证方法调用,您可以使用 Mockito 的 `verify()` 方法。该方法接受一个 Mock 对象和一个方法调用,并验证该方法是否被调用。例如,要验证 `UserService` 类的 `getUserById()` 方法是否被调用,您可以编写以下代码: ```java verify(userService).getUserById(1); ``` ### 完整示例 下面是一个完整的 Mockito 示例。在这个例子中,我们将创建一个名为 `UserServiceTest` 的测试类,并使用 Mockito 创建一个名为 `userService` 的 Mock 对象。然后,我们将设置 `userService` 的 `getUserById()` 方法调用返回一个名为 `John` 的用户。最后,我们将使用 Mockito 验证 `userService` 的 `getUserById()` 方法是否被调用。 ```java import org.junit.Test; import org.mockito.Mockito; import static org.mockito.Mockito.when; import static org.mockito.Mockito.verify; public class UserServiceTest { @Test public void testGetUserById() { // Create the mock object UserService userService = Mockito.mock(UserService.class); // Set the mock object's behavior User john = new User("John"); when(userService.getUserById(1)).thenReturn(john); // Call the method being tested User user = userService.getUserById(1); // Verify the method was called verify(userService).getUserById(1); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值