1 Star 0 Fork 0

gejin/springboot3-mockito

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

Getting Started

Reference Documentation

For further reference, please consider the following sections:

Maven Parent overrides

Due to Maven's design, elements are inherited from the parent POM to the project POM. While most of the inheritance is fine, it also inherits unwanted elements like <license> and <developers> from the parent. To prevent this, the project POM contains empty overrides for these elements. If you manually switch to a different parent and actually want the inheritance, you need to remove those overrides.

Springboot3, Mockito, JUnit5示例

学习使用JUnit 5Mockito测试框架为 Spring Boot 应用程序的服务层编写单元测试。我们在此演示中使用Spring Boot 3。对于 Spring Boot 应用程序,我们只需要更改 import 语句,一切都会自动运行。

@ExtendWith(MockitoExtension.class)
public class ItemServiceTest {

  @Mock
  private ItemRepository itemRepository;

  @InjectMocks
  private ItemService itemService; // 假设 ItemService 使用 ItemRepository

  @Test
  public void testCreateItem() {
  
      // ...
    }
}

1. Maven

spring-boot-starter-test依赖项会间接导入 JUnit 5 和 Mockito。因此我们只需要包含此依赖项。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

2. 初始化模拟

在这个例子中,我们主要对两个类EmployeeManagerEmployeeDao进行单元测试。顾名思义,manager 类代表服务层,而 dao 类与数据库交互。

EmployeeManager类依赖于EmployeeDao来从数据库获取数据,这些数据最终返回给控制器类。为了测试EmployeeManager中的方法,我们可以通过以下两种方式创建一个 JUnit 测试类TestEmployeeManager

2.1. @Mock 与 @InjectMocks

@Mock 注解为所注解的类创建一个模拟实现。

@InjectMocks还创建注解类型的模拟实现并将依赖的模拟注入其中。

在上面的例子中,我们用@InjectMocks注解了EmployeeManager类,因此 mockito 将为EmployeeManager类创建模拟对象,并将EmployeeDao的模拟依赖项注入其中。

2.2. 使用 MockitoExtension 进行初始化

要使用 JUnit 处理 Mockito 注释,我们需要使用MockitoExtention ,它会自动初始化所有带有@Mock@InjectMocks注释的对象。

@ExtendWith(MockitoExtension.class)
public class TestEmployeeManager {

	@InjectMocks
	EmployeeManager manager;

	@Mock
	EmployeeDao dao;

	//tests
}

2.3. 使用 MockitoAnnotations.openMocks() 进行初始化

如果我们不使用MockitoJUnitRunner类方法,那么我们可以使用静态方法 MockitoAnnotations.openMocks() 。在初始化 junit 测试时,此方法还会初始化模拟对象。

public class ServiceTests {

  @InjectMocks
  EmployeeService service;

  @Mock
  EmployeeRepository dao;

  @BeforeEach
  public void init() {
    MockitoAnnotations.openMocks(this);
  
  }

  //tests
}

3. Sprig 启动测试

让我们看几个编写 junit 测试的例子,使用 mockito 创建的模拟对象对服务层和DAO 层方法进行单元测试

一些示例方法可以是*getAllEmployees()*返回EmployeeVO对象列表、 <em>getEmployeeById(int id)</em>根据给定的 id 返回员工;以及createEmployee()添加员工对象并返回void

3.1. 单元测试示例

以下类包含服务类方法的测试。它使用*Mockito.when()*方法创建测试存根。

import com.mock.mockito.dao.EmployeeRepository;
import com.mock.mockito.entity.Employee;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.ArrayList;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class EmployeeServiceTest {
    @InjectMocks
    EmployeeService service;

    @Mock
    EmployeeRepository repository;

    /**
     * 保存对象的方法
     */
    @Test
    public void testSave(){
        Employee employee = new Employee("1", "2");
        Employee save = service.save(employee);
        assertEquals(save, null);
    }

    /**
     * 测试异常情况
     */
    @Test
    public void testSaveNull(){
        when(service.save(null)).thenThrow(new NullPointerException());
    }

    /**
     * 查询所有的数据
     *
     * @return list
     */
    @Test
    public  void testFindAllEmployees(){
        // 模拟从dao 层查询出所有数据
        List<Employee> list = initEmployees();
        when(repository.findAll()).thenReturn(list);

        // 调用service 层中的findAll() 方法查询数据
        List<Employee> all = service.findAll();

        // 判断两次查询的数据数量是否一致
        assertEquals(list.size(), all.size());
    }

    /**
     * 初始化数据
     *
     * @return list
     */
    private List<Employee> initEmployees() {
        List<Employee> list = new ArrayList<>();
        Employee empOne = new Employee("John", "John");
        Employee empTwo = new Employee("Alex", "kolenchiski");
        Employee empThree = new Employee("Steve", "Waugh");

        list.add(empOne);
        list.add(empTwo);
        list.add(empThree);
        return list;
    }
}

请注意,如果在测试执行期间未调用初始化的模拟,则Mockito会抛出UnsupportedStubbingException 。如果有此类可选的模拟行为,则使用Mockito.lenient() 如下所示:

Mockito.lenient().when(dao .isEmployeeDeleted()).thenReturn(Boolean.False);

3.2. 需要模拟的服务类

package com.mock.mockito.service;

import com.mock.mockito.dao.EmployeeRepository;
import com.mock.mockito.entity.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class EmployeeService {
    @Autowired
    EmployeeRepository employeeRepository;

    public Employee save(Employee employee) {
        //...
        if (employee != null){
            Employee save = employeeRepository.save(employee);
            return save;
        }else {
            throw new NullPointerException("the employee is not allowed be null");
        }
    }

    public List<Employee> findAll() {
        //...
        List<Employee> all = (List<Employee>) employeeRepository.findAll();
        return all;
    }

    public void deleteById(Integer id) {
        //...
        if (id != null){
            employeeRepository.deleteById(id);
        }else {
            throw new NullPointerException("the id is not allowed be null");
        }
    }

    public void deleteAll() {
        //...
        employeeRepository.deleteAll();
    }
}

实体类:

package com.mock.mockito.entity;

public class Employee {
    private String firstName;

    private String lastName;

    public Employee(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

dao层:

package com.mock.mockito.dao;

import com.mock.mockito.entity.Employee;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface EmployeeRepository extends CrudRepository<Employee, Integer> {
}

4. 结论

本 mockito 教程教我们使用 JUnit 和 Mockito 对 spring boot 应用程序中的服务层进行单元测试。我们学习了如何设置测试类和编写 JUnit 测试。我们还学习了*@Mock@InjectMocks*注释之间的区别。

空文件

简介

取消

发行版

暂无发行版

贡献者

全部

语言

近期动态

不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/githubGejin/springboot3-mockito.git
git@gitee.com:githubGejin/springboot3-mockito.git
githubGejin
springboot3-mockito
springboot3-mockito
master

搜索帮助