如何验证Mockito中被Mock构造函数的传入参数?
验证Mockito Mock构造函数的传入参数
针对你的问题,Mockito提供了简洁的方式捕获构造函数参数,无需采用单元素数组这类别扭的写法,以下是两种可行方案:
方案一:利用MockedConstruction.MockInitializer捕获参数
创建mockConstruction时传入初始化器lambda,直接从上下文获取构造参数并保存,后续即可验证参数是否符合预期。
修改后的测试代码:
import org.junit.jupiter.api.Test; import org.mockito.MockedConstruction; import static org.mockito.Mockito.mockConstruction; import static org.junit.jupiter.api.Assertions.*; @Test public void test_Target() { String capturedFirst = null; String capturedSecond = null; int capturedValue = 0; try (MockedConstruction<Mocked> mockedNew = mockConstruction(Mocked.class, (mock, context) -> { // 从构造上下文取出参数 capturedFirst = context.arguments().get(0); capturedSecond = context.arguments().get(1); capturedValue = (int) context.arguments().get(2); })) { new Target().testMe(); // 验证参数正确性 assertEquals("Hello", capturedFirst); assertEquals("World", capturedSecond); assertEquals(99, capturedValue); } }
context.arguments()会返回构造调用时的完整参数列表,可按索引和类型直接取出验证。
方案二:使用ArgumentCaptor配合构造函数验证
如果你更习惯Mockito传统的ArgumentCaptor验证风格,可通过以下方式实现:
import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.mockito.MockedConstruction; import static org.mockito.Mockito.*; @Test public void test_Target_WithArgumentCaptor() { ArgumentCaptor<String> firstArgCaptor = ArgumentCaptor.forClass(String.class); ArgumentCaptor<String> secondArgCaptor = ArgumentCaptor.forClass(String.class); ArgumentCaptor<Integer> valueArgCaptor = ArgumentCaptor.forClass(Integer.class); try (MockedConstruction<Mocked> mockedNew = mockConstruction(Mocked.class)) { new Target().testMe(); // 针对mock实例的构造方法调用进行验证,捕获参数 verify(mockedNew.constructed().get(0)).<String, String, Integer>construct( firstArgCaptor.capture(), secondArgCaptor.capture(), valueArgCaptor.capture() ); // 验证捕获的参数 assertEquals("Hello", firstArgCaptor.getValue()); assertEquals("World", secondArgCaptor.getValue()); assertEquals(99, valueArgCaptor.getValue()); } }
这里通过verify调用mock对象的construct方法(Mockito为构造函数生成的验证方法),配合泛型指定参数类型可避免强制类型转换问题。
补充说明
- 方案一更直接,适合简单参数验证场景;方案二更贴合Mockito传统验证风格,适配多次构造调用或复杂参数的场景。
- 两种方案均无需修改
Target或Mocked类,完全符合测试隔离原则。
内容的提问来源于stack exchange,提问作者Stormcloud
相关产品推荐
相关产品推荐

