Spring boot, mockito and junit – unit test service layer
学习使用**JUnit** 和 Mockito 测试框架为Spring 应用service层编写单元测试。这个教程演示_spring boot_ 测试service层案例。
1. Maven 依赖
spring-boot-starter-test 包含创建和执行单元测试的所有必须依赖。
pom.xml
1<dependency> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter-test</artifactId> 4</dependency>
如果你不使用 spring boot 你就需要加入下面的依赖:
pom.xml
1<dependency> 2 <groupId>junit</groupId> 3 <artifactId>junit</artifactId> 4 <version>4.12</version> 5 <scope>test</scope> 6</dependency> 7<dependency> 8 <groupId>org.mockito</groupId> 9 <artifactId>mockito-core</artifactId> 10 <version>2.15.0</version> 11</dependency> 12<dependency> 13 <groupId>org.mockito</groupId> 14 <artifactId>mockito-inline</artifactId> 15 <version>2.15.0</version> 16</dependency>
2. 创建项目
在这个案例中,我们的单元测试主要有2个classes EmployeeManager 和 EmployeeDao 顾名思义,manager class 代表是service 层 ,dao class 是和数据库打交道的。
EmployeeManager 依赖 EmployeeDao 并且委托方法调用获取数据,最终将数据返回到controller.
为了测试EmployeeManager 中的方法,我们可以通过以下2种方式创建TestEmployeeManager JUnit 单元测试类:
2.1. MockitoJUnitRunner class
MockitoJUnitRunner 自动初始化所有被@Mock 和 @InjectMocks 注解的对象。
TestEmployeeManager.java
1@RunWith(MockitoJUnitRunner.class) 2 3public class TestEmployeeManager { 4 @InjectMocks 5 EmployeeManager manager; 6 7 @Mock 8 EmployeeDao dao; 9 //tests 10}
2.2. MockitoAnnotations.initMocks() 方法
如果我们没有使用MockitoJUnitRunner 这种方式,那么我们可以使用static 方法MockitoAnnotations.initMocks()。这个方法,也能在初始化junit tests是,实例化mock 对象。
TestEmployeeManager.java
1public class TestEmployeeManager { 2 3 @InjectMocks 4 EmployeeManager manager; 5 6 @Mock 7 EmployeeDao dao; 8 9 @Before 10 public void init() { 11 MockitoAnnotations.initMocks(this); 12 } 13 //tests 14 15}
2.3. @Mock 与 @InjectMocks 对比
- The @Mock annotation creates a mock implementation for the class it is annotated with.
- @Mock 注解 可以为被注解的类创建一个模拟实现类。
- @InjectMocks also creates the mock implementation, additionally injects the dependent mocks that are marked with the annotations
@Mockinto it. - @InjectMocks 也可以创建模拟对象实现类,另外还可以为标记@Mock对象注入模拟对象实现
In above example, we have annotated EmployeeManager class with @InjectMocks, so mockito will create the mock object for EmployeeManager class and inject the mock dependency of EmployeeDao into it.
在上面的示例,我们EmployeeManager 被@InjectMocks注解 ,因此mockito 将会为EmployeeManager 创建模拟对象 并且注入模拟的对象依赖 EmployeeDao。
3. 在JUnit使用Mockito编写单元测试
让我们来看几个为service 层方法编写mockito 模拟对象的单元测试。
几个示例方法 getAllEmployees()将会返回EmployeeVO对象集合,getEmployeeById(int id)将会返回指定id employee 对象;
createEmployee()将会增加一个employee 并且返回 void。
3.1. Service 层单元测试
TestEmployeeManager.java
1package com.howtodoinjava.demo; 2 3import static org.junit.Assert.assertEquals; 4import static org.mockito.Mockito.times; 5import static org.mockito.Mockito.verify; 6import static org.mockito.Mockito.when; 7import java.util.ArrayList; 8import java.util.List; 9import org.junit.Before; 10import org.junit.Test; 11import org.junit.runner.RunWith; 12import org.mockito.InjectMocks; 13import org.mockito.Mock; 14import org.mockito.MockitoAnnotations; 15import org.mockito.junit.MockitoJUnitRunner; 16import com.howtodoinjava.demo.dao.EmployeeDao; 17import com.howtodoinjava.demo.model.EmployeeVO; 18import com.howtodoinjava.demo.service.EmployeeManager; 19 20public class TestEmployeeManager { 21 22 @InjectMocks 23 EmployeeManager manager; 24 25 @Mock 26 EmployeeDao dao; 27 28 @Before 29 public void init() { 30 MockitoAnnotations.initMocks(this); 31 } 32 33 @Test 34 public void getAllEmployeesTest() 35 { 36 List<EmployeeVO> list = new ArrayList<EmployeeVO>(); 37 EmployeeVO empOne = new EmployeeVO(1, "John", "John", "howtodoinjava@gmail.com"); 38 EmployeeVO empTwo = new EmployeeVO(2, "Alex", "kolenchiski", "alexk@yahoo.com"); 39 EmployeeVO empThree = new EmployeeVO(3, "Steve", "Waugh", "swaugh@gmail.com"); 40 41 list.add(empOne); 42 list.add(empTwo); 43 list.add(empThree); 44 45 when(dao.getEmployeeList()).thenReturn(list); 46 //test 47 List<EmployeeVO> empList = manager.getEmployeeList(); 48 assertEquals(3, empList.size()); 49 verify(dao, times(1)).getEmployeeList(); 50 } 51 52 @Test 53 public void getEmployeeByIdTest() 54 { 55 when(dao.getEmployeeById(1)).thenReturn(new EmployeeVO(1,"Lokesh","Gupta","user@email.com")); 56 EmployeeVO emp = manager.getEmployeeById(1); 57 assertEquals("Lokesh", emp.getFirstName()); 58 assertEquals("Gupta", emp.getLastName()); 59 assertEquals("user@email.com", emp.getEmail()); 60 } 61 62 @Test 63 public void createEmployeeTest() 64 { 65 EmployeeVO emp = new EmployeeVO(1,"Lokesh","Gupta","user@email.com"); 66 manager.addEmployee(emp); 67 verify(dao, times(1)).addEmployee(emp); 68 } 69}
单元测试的结果如下

Spring boot mockito junit 示例
3.2. Service 层
EmployeeManager.java
1import java.util.List; 2import org.springframework.beans.factory.annotation.Autowired; 3import org.springframework.stereotype.Service; 4import com.howtodoinjava.demo.dao.EmployeeDao; 5import com.howtodoinjava.demo.model.EmployeeVO; 6 7@Service 8public class EmployeeManager 9{ 10 @Autowired 11 EmployeeDao dao; 12 13 public List<EmployeeVO> getEmployeeList() { 14 return dao.getEmployeeList(); 15 } 16 17 public EmployeeVO getEmployeeById(int id) { 18 return dao.getEmployeeById(id); 19 } 20 21 public void addEmployee(EmployeeVO employee) { 22 dao.addEmployee(employee); 23 } 24}
3.3. Dao 层
EmployeeDao.java
1package com.howtodoinjava.demo.dao; 2 3import java.util.ArrayList; 4import java.util.HashMap; 5import java.util.List; 6import java.util.Map; 7import org.springframework.stereotype.Repository; 8import com.howtodoinjava.demo.model.EmployeeVO; 9 10@Repository 11public class EmployeeDao { 12 13 private Map<Integer, EmployeeVO> DB = new HashMap<>(); 14 15 public List<EmployeeVO> getEmployeeList() 16 { 17 List<EmployeeVO> list = new ArrayList<>(); 18 if(list.isEmpty()) { 19 list.addAll(DB.values()); 20 } 21 return list; 22 } 23 24 public EmployeeVO getEmployeeById(int id) { 25 return DB.get(id); 26 } 27 28 public void addEmployee(EmployeeVO employee) { 29 employee.setEmployeeId(DB.keySet().size() + 1); 30 DB.put(employee.getEmployeeId(), employee); 31 } 32 33 public void updateEmployee(EmployeeVO employee) { 34 DB.put(employee.getEmployeeId(), employee); 35 } 36 37 public void deleteEmployee(int id) { 38 DB.remove(id); 39 } 40 41}
4. Spring boot mockito example – 总结
在这个mockito 教程中,我们学到了在spring boot应用中如何使用JUnit 和 Mockito 为service层编写单元测试。学会创建和编写单元测试。
我们也学到了 注解**@Mock 和 @InitMocks 两者的区别。**
学的开心就好 !!
原文:https://howtodoinjava.com/spring-boot2/spring-boot-mockito-junit-example/