首页 > Java > java教程 > 正文

使用 Mockito 进行 Spring Boot Service 层单元测试

心靈之曲
发布: 2025-11-02 21:01:00
原创
493人浏览过

使用 mockito 进行 spring boot service 层单元测试

本文旨在指导开发者如何使用 Mockito 框架在 Spring Boot 项目中对 Service 层进行有效的单元测试。通过模拟(Mock)依赖的 DAO 或 Service,可以隔离被测 Service 的复杂性,专注于其自身的业务逻辑验证。本文将提供示例代码和详细步骤,帮助你编写可靠且易于维护的单元测试。

在 Spring Boot 应用中,Service 层通常依赖于多个 DAO (Data Access Object) 或其他的 Service。为了编写有效的单元测试,我们需要隔离被测 Service,避免依赖项的真实行为影响测试结果。Mockito 是一个流行的 Java 模拟框架,可以帮助我们实现这一点。

Mockito 简介

Mockito 允许我们创建模拟对象(Mock Objects),这些对象可以预先设定好行为,例如指定方法调用时的返回值或抛出异常。在单元测试中,我们可以使用 Mockito 来模拟 Service 依赖的 DAO 或其他 Service,从而专注于测试 Service 自身的业务逻辑。

示例代码

假设我们有以下 ExamServiceImpl 类:

青柚面试
青柚面试

简单好用的日语面试辅助工具

青柚面试57
查看详情 青柚面试
@Service
public class ExamServiceImpl implements ExamService {

    private final SubjectService subjectService;
    private final ScoreDAO scoreDAO;
    private final TeacherDAO teacherDAO;
    private final StudentDAO studentDAO;

    @Autowired
    public ExamServiceImpl(SubjectService subjectService, ScoreDAO scoreDAO, TeacherDAO teacherDAO, StudentDAO studentDAO) {
        this.subjectService = subjectService;
        this.scoreDAO = scoreDAO;
        this.teacherDAO = teacherDAO;
        this.studentDAO = studentDAO;
    }

    @Override
    public ResponseModel insertScore(RequestModel request) throws IOException {
        List<TeacherModel> teacher = teacherDAO.getNameList(request);
        List<StudentModel> student = studentDAO.findStudentList(teacher.get(0).getName(), request.getStudentScore());

        String nameStudent = student.get(0).getFirstName() + student.get(0).getLastName();
        SubjectModel subject = subjectService.getNameSubject(request, nameStudent);

        ScoreModel score = new ScoreModel();
        score.setStudentName(request.getStudentName());
        score.setScore(request.getStudentScore());
        score.setSubject(subject.getName);

        int result = scoreDAO.insert(score);

        return new ResponseModel(result);
    }
}
登录后复制

现在,我们来编写 ExamServiceImpl 的单元测试:

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 static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

@ExtendWith(MockitoExtension.class)
public class ExamServiceImplTest {

    @Mock
    private ScoreDAO scoreDAO;

    @Mock
    private SubjectService subjectService;

    @Mock
    private TeacherDAO teacherDAO;

    @Mock
    private StudentDAO studentDAO;

    @InjectMocks
    private ExamServiceImpl examService;

    @Test
    void insertScoreTest() throws IOException {
        // 1. 准备 Mock 对象和数据
        SubjectModel resFromSubject = new SubjectModel();
        resFromSubject.setSubject("Math");

        TeacherModel resTeacher = new TeacherModel();
        resTeacher.setName("test Teacher");
        List<TeacherModel> teacherList = Arrays.asList(resTeacher);

        StudentModel studentData = new StudentModel();
        studentData.setFirstName("firstname");
        studentData.setLastName("lastname");
        List<StudentModel> studentList = Arrays.asList(studentData);


        RequestModel request = new RequestModel();

        // 2. 设定 Mock 对象的行为
        when(teacherDAO.getNameList(any(RequestModel.class))).thenReturn(teacherList);
        when(studentDAO.findStudentList(anyString(), anyString())).thenReturn(studentList);
        when(subjectService.getNameSubject(any(RequestModel.class), anyString())).thenReturn(resFromSubject);
        when(scoreDAO.insert(any(ScoreModel.class))).thenReturn(1);

        // 3. 执行被测方法
        ResponseModel resultTest = examService.insertScore(request);

        // 4. 验证结果
        assertEquals(1, resultTest.getResult());
    }
}
登录后复制

代码解释

  1. @ExtendWith(MockitoExtension.class): 这个注解告诉 JUnit 使用 Mockito 扩展,以便自动初始化 Mock 对象。
  2. @Mock: 这个注解用于创建模拟对象。我们使用 @Mock 注解创建了 ScoreDAO, SubjectService, TeacherDAO, 和 StudentDAO 的模拟对象。
  3. @InjectMocks: 这个注解用于将模拟对象注入到被测对象中。我们使用 @InjectMocks 注解创建了 ExamServiceImpl 对象,并将上面创建的模拟对象注入到 ExamServiceImpl 中。
  4. when(...).thenReturn(...): 这个方法用于设定模拟对象的行为。例如,when(scoreDAO.insert(any(ScoreModel.class))).thenReturn(1) 表示当 scoreDAO.insert() 方法被调用时,无论传入什么参数,都返回 1。
  5. any(ScoreModel.class) 和 anyString(): 这些是 Mockito 提供的参数匹配器,用于匹配任意类型的参数。
  6. assertEquals(1, resultTest): 这是一个 JUnit 断言,用于验证测试结果是否符合预期。

注意事项

  • 确保你的测试类使用了 @ExtendWith(MockitoExtension.class) 注解,以便正确初始化 Mock 对象。
  • 使用 @Mock 注解创建模拟对象,并使用 @InjectMocks 注解将它们注入到被测对象中。
  • 使用 when(...).thenReturn(...) 方法设定模拟对象的行为。
  • 使用 any() 或 anyString() 等参数匹配器来匹配方法参数。
  • 使用 JUnit 断言来验证测试结果。
  • 为了使测试更具可读性,请遵循AAA模式(Arrange, Act, Assert):
    • Arrange (准备): 设置测试环境,包括创建 Mock 对象、设定 Mock 对象的行为、准备测试数据等。
    • Act (执行): 调用被测方法。
    • Assert (验证): 使用 JUnit 断言来验证测试结果。

总结

通过使用 Mockito,我们可以轻松地对 Spring Boot Service 层进行单元测试。Mockito 允许我们创建模拟对象,并设定它们的行为,从而隔离被测 Service 的复杂性,专注于其自身的业务逻辑验证。编写良好的单元测试可以提高代码质量、减少 bug,并提高代码的可维护性。 记住,良好的单元测试覆盖率是保证软件质量的关键因素之一。

以上就是使用 Mockito 进行 Spring Boot Service 层单元测试的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号