You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为EmployeeDaoImpl实现JdbcTemplate与RowMapper的Mock并设置ResultSet模拟数据

实现方案(基于Mockito框架)

我们可以通过Mockito拦截JdbcTemplate的query调用,同时模拟ResultSet和触发自定义RowMapper逻辑,完整实现步骤如下:

1. 依赖准备

确保项目引入JUnit 5和Mockito核心依赖,Maven示例配置:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>4.11.0</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>4.11.0</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.9.2</version>
    <scope>test</scope>
</dependency>

2. 测试类基础结构

import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.Mock;
import org.mockito.InjectMocks;
import org.junit.jupiter.api.extension.ExtendWith;

@ExtendWith(MockitoExtension.class)
public class EmployeeDaoImplTest {
    // Mock JdbcTemplate对象
    @Mock
    private JdbcTemplate jdbcTemplate;
    // 将Mock的JdbcTemplate注入到待测试的Dao类
    @InjectMocks
    private EmployeeDaoImpl employeeDao;
}

3. 核心测试逻辑实现

我们用Mockito的Answer机制拦截query调用,既可以验证入参正确性,也能覆盖你写的Lambda形式RowMapper的字段映射逻辑:

import org.junit.jupiter.api.Test;
import java.sql.ResultSet;
import java.util.Arrays;
import java.util.List;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;

@Test
public void testGetDetailsWithStatusNotNull() {
    // 1. 构造测试入参
    String testSql = "select dept_number, remarks from employee_task where ...";
    String countryCode = "CN";
    int departmentNumber = 10;
    Status status = Status.OK;
    int sectionNumber = 5;
    int aisle = 3;
    String zone = "A";

    // 2. Mock JdbcTemplate的query方法
    when(jdbcTemplate.query(anyString(), any(Object[].class), any(RowMapper.class))).thenAnswer(invocation -> {
        // 拿到方法调用时传入的自定义RowMapper
        RowMapper<EmployeeTask> rowMapper = invocation.getArgument(2);
        // 模拟ResultSet对象
        ResultSet mockRs = mock(ResultSet.class);

        // 模拟第一行数据
        when(mockRs.getInt("dept_number")).thenReturn(1001);
        when(mockRs.getString("remarks")).thenReturn("一号任务");
        EmployeeTask task1 = rowMapper.mapRow(mockRs, 1);

        // 模拟第二行数据
        when(mockRs.getInt("dept_number")).thenReturn(1002);
        when(mockRs.getString("remarks")).thenReturn("二号任务");
        EmployeeTask task2 = rowMapper.mapRow(mockRs, 2);

        // 返回构造好的结果列表
        return Arrays.asList(task1, task2);
    });

    // 3. 调用待测试方法
    List<EmployeeTask> result = employeeDao.getDetails(testSql, countryCode, departmentNumber, status, sectionNumber, aisle, zone);

    // 4. 断言结果符合预期
    assertEquals(2, result.size());
    assertEquals(1001, result.get(0).getDepatmentNumber());
    assertEquals("一号任务", result.get(0).getRemartks());
    // 也可以验证JdbcTemplate传入的参数是否正确
    verify(jdbcTemplate, times(1)).query(eq(testSql), any(Object[].class), any(RowMapper.class));
}

注意事项

  • 你提供的原代码存在两处可优化点:一是方法参数未定义sectionId但直接在参数数组中使用,二是setRemartks大概率是setRemarks的拼写错误,测试前建议先修正。
  • 如果你不需要验证RowMapper的映射逻辑,也可以直接让jdbcTemplate.query返回你预先构造好的List<EmployeeTask>,写法更简单,但无法覆盖Lambda内的逻辑。
  • status为空的测试场景只需把入参的status设为null,重复上述逻辑即可。

内容的提问来源于stack exchange,提问作者user15774463

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 01:21:04