使用Mockito ArgumentCaptor能否Mock修改入参的dao.load返回指定doc值
解决方案
实现方式
可以实现,无需修改现有业务代码,也不需要使用ArgumentCaptor,借助Mockito的Answer回调接口即可完成入参对象的赋值。
dao.load()方法接收的Document是引用类型参数,我们在Mock方法调用时,可以通过Answer拿到调用时实际传入的doc实例,直接对该实例的属性赋值,同时可以自定义返回的状态码rc,完全模拟真实DAO层的执行逻辑。
测试代码示例
import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; import static org.junit.Assert.*; @RunWith(MockitoJUnitRunner.class) public class DocumentControllerTest { // Mock DAO实例 @Mock private DocumentDAO dao; // 注入Mock依赖到待测试的Controller @InjectMocks private DocumentController documentController; @Test public void getDocumentSuccessTest() throws Exception { // 构造测试参数 int testId = 1001; String expectContent = "Mock的文档内容"; // 定义dao.load方法的Mock逻辑 when(dao.load(any(Document.class), eq(testId))).thenAnswer(invocation -> { // 取到调用时传入的第一个参数:业务代码中new的Document实例 Document inputDoc = invocation.getArgument(0); // 模拟DAO层填充文档属性 inputDoc.setId(testId); inputDoc.setContent(expectContent); // 返回成功状态码,可根据测试场景调整为异常状态码测试异常分支 return 0; }); // 执行待测试方法 Document result = documentController.getDocument(testId); // 校验结果 assertEquals(testId, result.getId()); assertEquals(expectContent, result.getContent()); } }
关于ArgumentCaptor的说明
ArgumentCaptor的核心作用是捕获方法调用时的入参值,用于后续验证参数是否符合预期,无法用来修改入参对象的内容,不适用当前需求场景。仅当你需要校验dao.load调用时传入的documentId是否正确时,才需要用到它,示例如下:
import static org.mockito.Mockito.verify; import org.mockito.ArgumentCaptor; // 执行测试方法后捕获参数 ArgumentCaptor<Integer> idCaptor = ArgumentCaptor.forClass(Integer.class); verify(dao).load(any(Document.class), idCaptor.capture()); // 验证传入的documentId是否符合预期 assertEquals(1001, idCaptor.getValue().intValue());
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

