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

如何在Spring Boot中使用Java和Mockito实现数据库表Mock?

注意:你示例代码中的Preciate为拼写错误,正确类名是JPA的Predicate接口。

测试JPA Criteria查询及Predicate逻辑的实现方案

以下提供两种可落地的实现方式,可根据测试场景选择:

方案1:Mockito模拟JPA组件快速验证(纯单元测试,无需启动数据库)

适合仅验证逻辑链路、Predicate条件构造是否符合预期的场景,执行速度快。

步骤1:初始化Mock对象

// 声明需要Mock的JPA核心组件
@Mock
private CriteriaBuilder criteriaBuilder;
@Mock
private Root<YourTableEntity> tableRoot;
@Mock
private CriteriaQuery<YourTableEntity> criteriaQuery;
@Mock
private Expression<String> colExpression;

// 被测业务类实例
private YourBusinessService service = new YourBusinessService();

@BeforeEach
void initMock() {
    MockitoAnnotations.openMocks(this);
    // 将Mock对象注入被测类
    service.setCriteriaBuilder(criteriaBuilder);
    service.setTableRoot(tableRoot);
    service.setCriteriaQuery(criteriaQuery);
}

步骤2:验证Predicate构造逻辑

@Test
void testMakePredicate() {
    String targetCol = "yourColName";
    // 模拟字段获取逻辑
    when(tableRoot.get(targetCol)).thenReturn(colExpression);
    // 构造模拟Predicate对象
    Predicate expectedPredicate = Mockito.mock(Predicate.class);
    when(criteriaBuilder.like(colExpression, "test")).thenReturn(expectedPredicate);

    // 执行被测方法
    Predicate actualPredicate = service.makePredicate();

    // 验证条件构造符合预期
    assertEquals(expectedPredicate, actualPredicate);
    verify(criteriaBuilder, times(1)).like(colExpression, "test");
}

步骤3:模拟ResultSet返回自定义测试数据

@Test
void testQueryResult() {
    // 构造模拟ResultSet并预设返回数据
    ResultSet mockRs = Mockito.mock(ResultSet.class);
    // 模拟返回2条符合条件的数据
    when(mockRs.next()).thenReturn(true, true, false);
    // 按行设置不同返回值
    when(mockRs.getInt("id")).thenAnswer(invocation -> mockRs.getRow());
    when(mockRs.getString("yourColName")).thenAnswer(invocation -> {
        return mockRs.getRow() == 1 ? "test1" : "test2";
    });
    // 模拟查询执行返回构造好的ResultSet
    when(criteriaQuery.getResultSet()).thenReturn(mockRs);

    // 执行业务查询逻辑
    criteriaQuery.where(service.makePredicate());
    ResultSet res = criteriaQuery.getResultSet();

    // 验证返回结果符合预期
    assertTrue(res.next());
    assertEquals(1, res.getInt("id"));
    assertEquals("test1", res.getString("yourColName"));
    assertTrue(res.next());
    assertEquals(2, res.getInt("id"));
    assertEquals("test2", res.getString("yourColName"));
    assertFalse(res.next());
}

方案2:内嵌H2内存数据库做集成测试(推荐验证查询正确性)

适合需要真实验证SQL条件是否生效、不会因为Mock逻辑偏差漏测的场景,支持真实的表创建、数据插入操作。

步骤1:引入H2依赖(Maven示例)

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>2.2.224</version>
    <scope>test</scope>
</dependency>

步骤2:测试类配置H2数据源并初始化测试数据

private Connection h2Conn;
private EntityManager entityManager;

@BeforeEach
void initH2() throws SQLException {
    // 启动内存级H2数据库
    h2Conn = DriverManager.getConnection("jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1", "sa", "");
    // 建表、插入自定义模拟数据
    try (Statement stmt = h2Conn.createStatement()) {
        stmt.execute("CREATE TABLE your_table (id INT PRIMARY KEY, your_col_name VARCHAR(255))");
        // 插入3条测试数据,其中2条符合like 'test%'的条件
        stmt.execute("INSERT INTO your_table VALUES (1, 'test1'), (2, 'test2'), (3, 'abc')");
    }
    // 初始化关联H2的JPA组件
    entityManager = Persistence.createEntityManagerFactory("testPersistenceUnit").createEntityManager();
}

@Test
void testRealQueryLogic() {
    CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    CriteriaQuery<YourTableEntity> query = cb.createQuery(YourTableEntity.class);
    Root<YourTableEntity> root = query.from(YourTableEntity.class);

    // 执行你的业务查询逻辑
    query.where(cb.like(root.get("yourColName"), "test%"));
    List<YourTableEntity> resultList = entityManager.createQuery(query).getResultList();

    // 验证实际查询结果符合预期
    assertEquals(2, resultList.size());
    assertEquals("test1", resultList.get(0).getYourColName());
    assertEquals("test2", resultList.get(1).getYourColName());
}

@AfterEach
void closeResource() throws SQLException {
    h2Conn.close();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 06:39:03