首页 > Java > java教程 > 正文

使用 Mockito 进行单元测试时thenReturn()失效的解决方案

碧海醫心
发布: 2025-10-13 11:32:40
原创
904人浏览过

使用 mockito 进行单元测试时thenreturn()失效的解决方案

本文旨在解决在使用 Mockito 框架进行单元测试时,thenReturn() 方法无法正常工作,导致模拟对象返回空值的问题。通过示例代码和详细步骤,帮助开发者正确配置和使用 Mockito,确保单元测试的有效性。

在使用 Mockito 进行单元测试时,经常会遇到 thenReturn() 方法失效,导致模拟对象返回 null 的情况。这个问题通常是由于 Mockito 的初始化不正确导致的。下面将详细介绍如何正确配置和使用 Mockito,解决 thenReturn() 失效的问题。

问题分析

当 loginDao.getAdminDetails(anyString(), anyString()) 返回 null,并且抛出 UnnecessaryStubbingException 异常时,说明 Mockito 没有正确地初始化 Mock 对象,或者 Mock 对象没有被正确地注入到被测试的类中。

解决方案

解决这个问题的关键在于正确初始化 Mockito 的 Mock 对象,并将它们注入到被测试的类中。以下是两种常用的解决方案:

1. 使用 MockitoAnnotations.initMocks(this)

这种方法需要在测试类的 setUp 方法中使用 MockitoAnnotations.initMocks(this) 来初始化 Mockito。这会扫描测试类中所有带有 @Mock 注解的字段,并创建它们的 Mock 对象。同时,它还会扫描带有 @InjectMocks 注解的字段,并将 Mock 对象注入到这些字段中。

FashionLabs
FashionLabs

AI服装模特、商品图,可商用,低价提升销量神器

FashionLabs 38
查看详情 FashionLabs
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.servlet.ModelAndView;

import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;

class LoginControllerTest {

    @InjectMocks
    LoginController loginController;

    @Mock
    CustomerDao customerDao;

    @Mock
    Customer customer;

    @Mock
    InvoiceDao invoiceDao;

    @Mock
    DashboardDao dashboardDao;

    @Mock
    LoginDao loginDao;

    @Mock
    Admin admin;

    @BeforeEach
    void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    void testLogin() throws Exception {

        MockHttpServletRequest request = new MockHttpServletRequest();
        MockHttpServletResponse response = new MockHttpServletResponse();

        request.setParameter("password", "pass");
        request.setParameter("username", "uname");

        when(loginDao.getAdminDetails(anyString(), anyString())).thenReturn(admin);

        ModelAndView modelAndView = loginController.login(request, response);
        assertNotNull(modelAndView);
    }
}
登录后复制

注意事项:

  • 确保在测试方法执行之前调用 MockitoAnnotations.initMocks(this)。
  • 将 setUp 方法使用 @BeforeEach 注解标记,以确保在每个测试方法执行之前都会执行初始化操作。

2. 使用 JUnit Runner 初始化 Mockito

另一种方法是使用 JUnit 提供的 Runner 来初始化 Mockito。这可以通过在测试类上添加 @RunWith(MockitoJUnitRunner.class) 注解来实现。

import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.servlet.ModelAndView;

import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
class LoginControllerTest {

    @InjectMocks
    LoginController loginController;

    @Mock
    CustomerDao customerDao;

    @Mock
    Customer customer;

    @Mock
    InvoiceDao invoiceDao;

    @Mock
    DashboardDao dashboardDao;

    @Mock
    LoginDao loginDao;

    @Mock
    Admin admin;

    @Test
    void testLogin() throws Exception {

        MockHttpServletRequest request = new MockHttpServletRequest();
        MockHttpServletResponse response = new MockHttpServletResponse();

        request.setParameter("password", "pass");
        request.setParameter("username", "uname");

        when(loginDao.getAdminDetails(anyString(), anyString())).thenReturn(admin);

        ModelAndView modelAndView = loginController.login(request, response);
        assertNotNull(modelAndView);
    }
}
登录后复制

注意事项:

  • 确保添加了 org.mockito.junit.MockitoJUnitRunner 依赖。
  • 这种方法不需要显式调用 MockitoAnnotations.initMocks(this),JUnit 会自动完成初始化。

示例代码解释

  • @InjectMocks 注解:用于标记需要注入 Mock 对象的类,例如 LoginController。
  • @Mock 注解:用于标记需要创建 Mock 对象的类,例如 LoginDao 和 Admin。
  • when(loginDao.getAdminDetails(anyString(), anyString())).thenReturn(admin):这行代码用于指定当调用 loginDao.getAdminDetails() 方法时,返回 admin 对象。anyString() 方法表示匹配任何字符串参数。
  • assertNotNull(modelAndView):这行代码用于断言 login() 方法返回的 ModelAndView 对象不为空。

总结

通过正确初始化 Mockito,并使用 @Mock 和 @InjectMocks 注解,可以有效地解决 thenReturn() 方法失效的问题。选择哪种初始化方式取决于个人偏好和项目需求。 无论选择哪种方法,都需要确保 Mock 对象被正确地创建和注入到被测试的类中,才能保证单元测试的有效性。 此外,确保你的 Mockito 和 JUnit 版本兼容,避免因版本问题导致初始化失败。

以上就是使用 Mockito 进行单元测试时thenReturn()失效的解决方案的详细内容,更多请关注php中文网其它相关文章!

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

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

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

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