如何在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
相关产品推荐
相关产品推荐

