跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

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

本文旨在解决在使用 Mockito 框架进行单元测试时,thenReturn() 方法无法正常工作,导致模拟对象返回空值的问题。通过示例代码和详细步骤,帮助开发者正确配置和使用 Mockito,确保单元测试的有效性。 在使用 Mockito 进行单元测试时,经常会遇到 thenReturn() 方法失效,导致模拟对象返回 null 的情况。这个问题通常是由于 Mockito 的初始化不正确导致的。下面将详细介绍如何正确配置和使用 Mockito,解决 thenReturn() 失效的问题。 问题分析 当 loginDao.getAdminDetails(anyString(), anyString()) 返回 null,并且抛出 UnnecessaryStub bing Exception 异常时,说明 Mockito 没有正确地初始化 Mock 对象,或者 Mock 对象没有被正确地注入到被测试的类中。 解决方案 解决这个问题的关键在于正确初始化 Mockito 的 Mock 对象,并将它们注入到被测试的类中。以下是两种常用的解决方案: 1. 使用 MockitoAnnotations.initMocks(this) 这种方法需要在测试类的 setUp 方法中使用 MockitoAnnotations.initMocks(this) 来初始化 Mockito。这会扫描测试类中所有带有 @Mock 注解的字段,并创建它们的 Mock 对象。同时,它还会扫描带有 @InjectMocks 注解的字段,并将 Mock 对象注入到这些字段中。 New Bing 微软new必应,集成GPT4模型的新一代搜索引擎,New Bing不仅提供了快速、准确、全面的搜索结果,还可以与用户进行自然、有趣、有用的对话,为用户提供更多的信息和服务。 下载
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 版本兼容,避免因版本问题导致初始化失败。

相关文章