“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这两种场景进行展开介绍,文章末尾附带代码链接。
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>
针对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一起使用。
junit5与junit4区别比较大,junit5使用了大量的jdk8特性、lamda表达式。
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>
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
(以上内容为DreamKite本人原创,转载请附上原文链接)