Mockito校验FooWriter的write方法时传入anyList编译报错,求解决
问题修复与正确测试写法
你的测试代码有几个明显问题,导致编译报错还没法达到“不写库只校验”的目的:
- Mockito的verify用错了:verify的参数得是被Mock/Spy的对象,不能直接传
fooWriter.write(...)的调用结果,正确格式是verify(对象).方法(参数匹配器)。 - 参数匹配器写法不对:
anyList(List<Foo>)是错误用法,应该用anyList()或者anyListOf(Foo.class)。 - verify的时机错了:要先调用
fooWriter.write(fooList),再用verify校验方法被调用过,不能在@Before里就校验。 - 没处理真实写入的问题:只用@InjectMocks会创建真实的FooWriter实例,会真的往数据库写数据,得用@Spy来部分Mock,或者直接Mock整个FooWriter。
两种正确的测试代码示例
写法1:用Spy保留子类逻辑,阻止父类真实写入
适合你需要验证FooWriter的write方法确实调用了父类逻辑,但又不想真的写数据库的场景:
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Spy; import org.mockito.junit.jupiter.MockitoExtension; import java.util.ArrayList; import java.util.List; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.verify; import static org.mockito.ArgumentMatchers.anyList; @ExtendWith(MockitoExtension.class) class FooWriterTest { @Spy @InjectMocks FooWriter fooWriter; List<Foo> fooList = new ArrayList<>(); @Test void testWrite() throws Exception { // 阻止父类的write方法执行真实数据库操作 doNothing().when(fooWriter).write(anyList()); // 调用要测试的方法 fooWriter.write(fooList); // 校验write方法确实被调用,传入的是预期的list verify(fooWriter).write(fooList); // 如果不关心具体list,也可以用匹配器校验任意Foo类型的list // verify(fooWriter).write(anyListOf(Foo.class)); } }
写法2:直接Mock整个FooWriter
如果只需要校验write方法被调用过,不需要执行FooWriter自身的逻辑,直接Mock就行:
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import java.util.ArrayList; import java.util.List; import static org.mockito.Mockito.verify; import static org.mockito.ArgumentMatchers.anyList; @ExtendWith(MockitoExtension.class) class FooWriterTest { @Mock FooWriter fooWriter; List<Foo> fooList = new ArrayList<>(); @Test void testWrite() throws Exception { // 调用方法 fooWriter.write(fooList); // 校验方法被调用 verify(fooWriter).write(fooList); // 或者用匹配器匹配任意List // verify(fooWriter).write(anyList()); } }
额外说明
- @Spy:用来包装真实对象,可以针对性地屏蔽某些方法(比如父类的write),同时保留其他方法的真实逻辑,适合需要验证子类方法行为的场景。
- doNothing():用来屏蔽无返回值的方法,避免执行真实的数据库写入逻辑。
- 参数匹配器:
anyList()匹配任意List对象,anyListOf(Foo.class)专门匹配泛型为Foo的List,按需选用。
内容的提问来源于stack exchange,提问作者likejudo
相关产品推荐
相关产品推荐

