Spring boot, mockito and junit – unit test service layer
学习使用**JUnit** 和 Mockito 测试框架为Spring 应用service层编写单元测试。这个教程演示_spring boot_ 测试service层案例。
1. Maven 依赖
spring-boot-starter-test 包含创建和执行单元测试的所有必须依赖。
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
如果你不使用 spring boot 你就需要加入下面的依赖:
pom.xml
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.15.0</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>2.15.0</version>
</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
@RunWith(MockitoJUnitRunner.class)
public class TestEmployeeManager {
@InjectMocks
EmployeeManager manager;
@Mock
EmployeeDao dao;
//tests
}
2.2. MockitoAnnotations.initMocks() 方法
如果我们没有使用MockitoJUnitRunner 这种方式,那么我们可以使用static 方法MockitoAnnotations.initMocks()。这个方法,也能在初始化junit tests是,实例化mock 对象。
TestEmployeeManager.java
public class TestEmployeeManager {
@InjectMocks
EmployeeManager manager;
@Mock
EmployeeDao dao;
@Before
public void init() {
MockitoAnnotations.initMocks(this);
}
//tests
}
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
@Mock
into 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
package com.howtodoinjava.demo;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import com.howtodoinjava.demo.dao.EmployeeDao;
import com.howtodoinjava.demo.model.EmployeeVO;
import com.howtodoinjava.demo.service.EmployeeManager;
public class TestEmployeeManager {
@InjectMocks
EmployeeManager manager;
@Mock
EmployeeDao dao;
@Before
public void init() {
MockitoAnnotations.initMocks(this);
}
@Test
public void getAllEmployeesTest()
{
List<EmployeeVO> list = new ArrayList<EmployeeVO>();
EmployeeVO empOne = new EmployeeVO(1, "John", "John", "howtodoinjava@gmail.com");
EmployeeVO empTwo = new EmployeeVO(2, "Alex", "kolenchiski", "alexk@yahoo.com");
EmployeeVO empThree = new EmployeeVO(3, "Steve", "Waugh", "swaugh@gmail.com");
list.add(empOne);
list.add(empTwo);
list.add(empThree);
when(dao.getEmployeeList()).thenReturn(list);
//test
List<EmployeeVO> empList = manager.getEmployeeList();
assertEquals(3, empList.size());
verify(dao, times(1)).getEmployeeList();
}
@Test
public void getEmployeeByIdTest()
{
when(dao.getEmployeeById(1)).thenReturn(new EmployeeVO(1,"Lokesh","Gupta","user@email.com"));
EmployeeVO emp = manager.getEmployeeById(1);
assertEquals("Lokesh", emp.getFirstName());
assertEquals("Gupta", emp.getLastName());
assertEquals("user@email.com", emp.getEmail());
}
@Test
public void createEmployeeTest()
{
EmployeeVO emp = new EmployeeVO(1,"Lokesh","Gupta","user@email.com");
manager.addEmployee(emp);
verify(dao, times(1)).addEmployee(emp);
}
}
单元测试的结果如下
Spring boot mockito junit 示例
3.2. Service 层
EmployeeManager.java
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.howtodoinjava.demo.dao.EmployeeDao;
import com.howtodoinjava.demo.model.EmployeeVO;
@Service
public class EmployeeManager
{
@Autowired
EmployeeDao dao;
public List<EmployeeVO> getEmployeeList() {
return dao.getEmployeeList();
}
public EmployeeVO getEmployeeById(int id) {
return dao.getEmployeeById(id);
}
public void addEmployee(EmployeeVO employee) {
dao.addEmployee(employee);
}
}
3.3. Dao 层
EmployeeDao.java
package com.howtodoinjava.demo.dao;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Repository;
import com.howtodoinjava.demo.model.EmployeeVO;
@Repository
public class EmployeeDao {
private Map<Integer, EmployeeVO> DB = new HashMap<>();
public List<EmployeeVO> getEmployeeList()
{
List<EmployeeVO> list = new ArrayList<>();
if(list.isEmpty()) {
list.addAll(DB.values());
}
return list;
}
public EmployeeVO getEmployeeById(int id) {
return DB.get(id);
}
public void addEmployee(EmployeeVO employee) {
employee.setEmployeeId(DB.keySet().size() + 1);
DB.put(employee.getEmployeeId(), employee);
}
public void updateEmployee(EmployeeVO employee) {
DB.put(employee.getEmployeeId(), employee);
}
public void deleteEmployee(int id) {
DB.remove(id);
}
}
4. Spring boot mockito example – 总结
在这个mockito 教程中,我们学到了在spring boot应用中如何使用JUnit 和 Mockito 为service层编写单元测试。学会创建和编写单元测试。
我们也学到了 注解**@Mock 和 @InitMocks 两者的区别。**
学的开心就好 !!
原文:https://howtodoinjava.com/spring-boot2/spring-boot-mockito-junit-example/