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

使用ArgumentCaptor捕获PreparedStatementCreator内部调用的测试

使用ArgumentCaptor捕获PreparedStatementCreator的内部调用

我先把你提供的业务代码和测试片段用规范的Markdown格式整理好,还补全了测试代码的完整实现,方便你直接参考:

业务实现代码

public void update(Item item) { 
    String sql = "SET NAME = ? where ID = ?"; 
    jdbcTemplate.update(new PreparedStatementCreator() { 
        @Override 
        public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { 
            final PreparedStatement ps = connection.prepareStatement(sql); 
            ps.setString(1, item.getName()); 
            ps.setInt(1, item.getId()); // 这里注意参数索引重复了,应该用2哦
        } 
    }); 
}

小提示:业务代码里的ps.setInt(1, item.getId())参数索引写错啦,应该用2才对,不然会覆盖之前设置的name参数。

完整测试代码实现

你提供的测试片段不完整,我帮你补全了完整的测试逻辑,展示如何用ArgumentCaptor捕获PreparedStatementCreator并验证内部的参数设置:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import static org.mockito.Mockito.*;

@RunWith(MockitoJUnitRunner.class)
public class YourServiceTest {

    @Mock
    private JdbcTemplate jdbcTemplate;

    @Mock
    private Connection connection;

    @Mock
    private PreparedStatement preparedStatement;

    @InjectMocks
    private YourService yourService; // 替换成你的实际业务类名

    @Test
    public void testUpdate() throws SQLException {
        // 1. 创建ArgumentCaptor来捕获PreparedStatementCreator类型的参数
        ArgumentCaptor<PreparedStatementCreator> captor = ArgumentCaptor.forClass(PreparedStatementCreator.class);

        // 2. 模拟Connection.prepareStatement的返回值
        when(connection.prepareStatement(anyString())).thenReturn(preparedStatement);

        // 3. 创建测试用的Item对象
        Item testItem = new Item();
        testItem.setId(123);
        testItem.setName("TestName");

        // 4. 调用目标方法
        yourService.update(testItem);

        // 5. 捕获传入jdbcTemplate.update的PreparedStatementCreator参数
        verify(jdbcTemplate).update(captor.capture());
        PreparedStatementCreator creator = captor.getValue();

        // 6. 调用creator的createPreparedStatement方法,触发内部的参数设置逻辑
        creator.createPreparedStatement(connection);

        // 7. 验证参数设置是否正确(这里注意修正业务代码里的索引后,应该验证索引1和2)
        verify(preparedStatement).setString(1, "TestName");
        verify(preparedStatement).setInt(2, 123);
    }
}

关键步骤说明

  • 用ArgumentCaptor<PreparedStatementCreator>捕获传入jdbcTemplate.update的匿名内部类实例
  • 通过verify(jdbcTemplate).update(captor.capture())完成捕获操作
  • 调用捕获到的creator.createPreparedStatement(connection),触发内部的ps.setString和ps.setInt逻辑
  • 最后用Mockito的verify方法验证参数设置是否符合预期

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:07:41