springboot使用Mockito和Junit进行测试代码编写

摘要

“Mockito + junit + springboot” 搞定UT用例的复杂场景数据模拟

一、背景分析

  • 目前主流的junit框架是junit4 和junit5,junit4的好处是资料和搭配使用的模块目前较多,junit5的优点是使用起来更加方便更加友好

  • 在编写UT数据模拟这块junit的功能明显是不足的,因此我们常常还需要跟Mockito进行搭配,覆盖我们java项目开发的一些常见的场景(本文以目前主流开发的springboot场景进行讲解)

  • SpringBoot1.X版本默认使用的Junit4.X的版本,而SpringBoot2.X版本默认使用的junit5.X,说明主流的搭配也该如此,因此建议大家升级到springboot2.X也升级一下junit,短期方案可以在pom文件中指定junit使用版本为4.X

本文将对springboot1.X+junit4和springboot2.X+junit5这两种场景进行展开介绍,文章末尾附带代码链接

二、springboot1.X+junit4

pom

spring-boot-starter-test 中默认集成了Mockito,则不需要额外引入。非springboot项目则引入方式如下:

<dependency>
	<groupId>junitgroupId>
    <artifactId>junitartifactId>
    <version>4.12version>
dependency>
<dependency>
	<groupId>org.mockitogroupId>
    <artifactId>mockito-coreartifactId>
    <version>1.10.19version>
dependency>

code

针对Springboot1.X的情况,mockito需要添加@RunWith(MockitoJUnitRunner.class)

如果使用的Junit + mockito联合测试,那应该使用的@RunWith(SpringJunit4ClassRunner.class), 这时候需要再添加mockito的初始化(可通过@Run public MockitoRule mockitoRule = MockitoJunit.rule();实现), 两种场景如下代码

package com.dreamkite.pg.controller;

@ActiveProfiles({"test"})
@SpringBootTest(classes = {MockitoJUnitRunner.class})
@RunWIth(SpringJunit4ClassRunner.class)
class AControllerTest {
    @Autowired
    @InjectMocks
    private AController aController;

    @Mock
    private PersonService personService;

    @Test
    void hi() {
        Mockito.doReturn("hjk").when(personService).hi();

        Assert.assert("hjk", aController.hi());
    }
}

第二种会启动springboot服务

package com.dreamkite.pg.controller;

@ActiveProfiles({"test"})
@SpringBootTest(classes = {UsePgApplication.class})
@RunWIth(SpringJunit4ClassRunner.class)
class AControllerTest {
    @Run 
    public MockitoRule mockitoRule = MockitoJunit.rule();

    @Autowired
    @InjectMocks
    private AController aController;

    @Mock
    private PersonService personService;

    @Test
    void hi() {
        Mockito.doReturn("hjk").when(personService).hi();

        Assert.assert("hjk", aController.hi());
    }
}

代码补充说明:

@Mock创建的全部mock的对象,即在对具体的方法打桩前,mock对象的所有属性和方法全部置为空(0或null);

@injectMocks创建的对象,其内部的对象没有被@Mock进行注解的对象则为0或null,如果需要injectMocks注解的对象除了装配Mock的对象,其他内部对象能自动装配,则要跟@Autowired一起使用。

三、springboot2.X+junit5

junit5与junit4区别比较大,junit5使用了大量的jdk8特性、lamda表达式。

pom

spring-boot-starter-test 中默认集成了Mockito,则不需要额外引入。非springboot项目则引入方式如下:

<dependency>
	<groupId>junitgroupId>
    <artifactId>junitartifactId>
    <version>5.3.1version>
    <scope>testscope>
dependency>
<dependency>
	<groupId>org.mockitogroupId>
    <artifactId>mockito-coreartifactId>
    <version>2.21.0version>
    <scope>testscope>
dependency>

Code

package com.dreamkite.pg.controller;

import com.dreamkite.pg.UsePgApplication;
import com.dreamkite.pg.service.PersonService;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import static org.junit.jupiter.api.Assertions.*;

@ActiveProfiles({"test"})
@SpringBootTest(classes = {UsePgApplication.class})
@ExtendWith(SpringExtension.class)
@ExtendWith({MockitoExtension.class})
class AControllerTest {

    @Autowired
    @InjectMocks
    private AController aController;

    @Mock
    private PersonService personService;

    @Test
    void hi() {
        Mockito.doReturn("hjk").when(personService).hi();
        
        assertEquals("hjk", aController.hi());
    }
}

见github链接:https://github.com/junkaitongxue/LearnSpringBoot/blob/main/usePostgres/src/test/java/com/dreamkite/pg/controller/AControllerTest.java

四、相关链接:

  • Spring依赖注入与mock
  • 使用Junit + Mockito实践单元测试
  • Mockito框架@Mock, @InjectMocks注解使用
  • 如何在Junit中使用@InjectMocks和@Autowired注释

(以上内容为DreamKite本人原创,转载请附上原文链接)

你可能感兴趣的:(后端开发,开发者测试,经验分享,spring,boot,java,后端,单元测试)