【Mockito】SpringBoot中的应用笔记

目录

依赖

 验证和断言

注解

Spy

mock静态方法

单元测试实例


Mock 可以理解为创建一个虚拟的对象,在测试环境用来替换真实的对象,从而验证

  • 该对象的某些方法,调用次数,参数
  • 指定返回结果或指定特定动作

Mockito framework site

依赖

       
            org.springframework.boot
            spring-boot-starter-test
            test
            
                
                    org.mockito
                    mockito-core
                
            
        










        
            org.mockito
            mockito-inline
            4.3.1
            test
        

案例

package com.example.demo;

/**
 * @author: xxx
 * @date: 2023/7/11 18:21
 */
public class Demo {

//    静态有参
    public static Integer id(Integer id){
        return id;
    }
//    静态无参
    public static String name(){
        return "xxx";
    }



    public int add(int a, int b){
        return a + b;
    }



}

 验证和断言

  • 验证:验证待验证的对象是否发生过某些行为
  • 断言:判断返回的结果 的 数据类型 是否是我们符合的类型
@SpringBootTest
class DemoApplicationTests {

    @Test
    void testAdd() {
        //mock-一个Random类
        Random random = Mockito.mock(Random.class);
        System.out.println(random.nextInt());

        //验证:验证待验证的对象是否发生过某些行为
//        断言:判断返回的结果 的 数据类型 是否是我们符合的类型

        //验证 verify 配合time()使用  可以验证某些操作发生的次数
        //表示 调用 random类的 nextInt()函数两次
        //如果 不一样 日志会提示
        /**
         * org.mockito.exceptions.verification.TooFewActualInvocations:
         * random.nextInt();
         * Wanted 2 times:
         * -> at com.example.demo.DemoApplicationTests.testAdd(DemoApplicationTests.java:19)
         * But was 1 time:
         * -> at com.example.demo.DemoApplicationTests.testAdd(DemoApplicationTests.java:18)
         */
        Mockito.verify(random,Mockito.times(2)).nextInt();

        //断言
        //当调用nextInt()时返回100
        Mockito.when(random.nextInt()).thenReturn(100);  //打桩
        Assertions.assertEquals(100, random.nextInt());  //预期返回值为100

    }

}

注解

@Mock

@BeforeEach

@AfterEach

package com.example.demo;

import com.example.demo.annotation.Student;
import org.junit.jupiter.api.*;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Random;

@SpringBootTest
class DemoApplicationTests {

    @Mock
    private Random random;
//    Random random = Mockito.mock(Random.class);

    @BeforeEach//在每个测试方法前
    void setUp(){
        MockitoAnnotations.openMocks(this);//@Mock需要和这个方法一块使用
        System.out.println("测试前准备");
    }

    @AfterEach
    void after(){
        System.out.println("测试结束");
    }


    @Test
    void testAdd() {
       
    }

}

Spy

  • 被spy的对象会走真实的方法,而mock对象不会
  • spy()方法的参数是对象实例,mock的参数是class
package com.example.demo;

import com.example.demo.annotation.Student;
import org.junit.jupiter.api.*;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Random;

@SpringBootTest
class DemoApplicationTests {

    @Spy
    private Demo demo;
//    Random random = Mockito.mock(Random.class);

    @BeforeEach//在每个测试方法前
    void setUp(){
        System.out.println("测试前准备");
        MockitoAnnotations.openMocks(this);//@Mock需要和这个方法一块使用
    }

    @AfterEach
    void after(){
        System.out.println("测试结束");
    }


    @Test
    void testAdd() {
        //打桩
        Mockito.when(demo.add(1, 2)).thenReturn(0);
        //没有打桩的话走真实的方法,打桩的话走,打桩的方法。
        /**
         * org.opentest4j.AssertionFailedError: 
         * Expected :3
         * Actual   :0
         * 
         */
        Assertions.assertEquals(3, demo.add(1, 2));

    }

}

mock静态方法

  • 静态有参
  • 静态无参 
package com.example.demo;

import com.example.demo.annotation.Student;
import org.junit.jupiter.api.*;
import org.mockito.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Random;

@SpringBootTest
class DemoApplicationTests {

    @Spy
    private Demo demo;

    @BeforeEach//在每个测试方法前
    void setUp(){
        System.out.println("测试前准备");
        MockitoAnnotations.openMocks(this);//@Mock需要和这个方法一块使用
    }

    @AfterEach
    void after(){
        System.out.println("测试结束");
    }


    @Test
    void testAdd() {
        //抛出一个RuntimeException,用于try catch等测试不同 情况
        Mockito.when(demo.add(1,1)).thenThrow(new RuntimeException());
        demo.add(1,1);

        //走真实的方法
        Mockito.when(demo.add(1,2)).thenCallRealMethod();
        Assertions.assertEquals(2,demo.add(1,2));

        //3.4
    }

    @Test
    void testId(){
//try-resource 关闭资源
        try (MockedStatic demo = Mockito.mockStatic(Demo.class)) {
            demo.when(() -> Demo.id(1)).thenReturn(1);
            Assertions.assertTrue(Demo.id(1)==1);
        }

    }

    @Test
    void testName(){
        try (MockedStatic demo = Mockito.mockStatic(Demo.class)) {
            demo.when(Demo::name).thenReturn("guitu");
            Assertions.assertEquals("xxx",Demo.name());
        }
    }

}

单元测试实例

【Mockito】单元测试如何提升代码覆盖率_哔哩哔哩_bilibili

来源:

【Mockito】Mockito + Junit 5 快速入门_哔哩哔哩_bilibili 

你可能感兴趣的:(后端开发,开发语言,单元测试)