Mockito验证ArrayList大小:无视图时如何验证getItemCount方法?
解决Mockito验证getItemCount时的NotAMockException问题
你遇到的NotAMockException是因为用错了Mockito的verify()方法——它可不是用来断言返回值的,而是用来验证Mock/Spy对象的方法调用行为的,而你把一个普通int值(songList.size()的结果)传给了verify(),这完全不符合它的用法。
咱们一步步来修复这个问题:
首先搞清楚问题根源
你的SongAdapterPresenter.getItemCount()逻辑是返回songs列表的长度,但当前测试里有两个核心问题:
- 测试用的
songList根本没传给SongAdapterPresenter,所以它内部的songs还是null,调用getItemCount()只会返回0; - 用
verify(songList.size()).equals(1)是完全错误的:verify()参数必须是Mock/Spy对象,你传了个int值,Mockito自然报错。
解决方案步骤
1. 让Presenter能接收测试用的歌曲列表
如果你的SongAdapterPresenter还没有设置歌曲列表的方法,先加一个setter(或者如果是通过构造传入的话,修改构造方法):
public class SongAdapterPresenter implements SortedSongSelectionContract.SongAdapterContract.Presenter { // ... 其他代码 ... private List<Song> songs; // 添加setter方法 public void setSongs(List<Song> songs) { this.songs = songs; } @Override public int getItemCount() { return songs != null ? songs.size() : 0; } }
2. 修正测试方法,用JUnit断言验证返回值
我们的目标是验证getItemCount()的返回结果是否正确,这属于结果断言,用JUnit的assertEquals就可以了,不需要Mockito的verify。修正后的测试代码:
@Test public void testGetItemCount(){ // 把测试用的songList设置到Presenter中 songAdapterPresenter.setSongs(songList); // 调用方法并获取返回值 int itemCount = songAdapterPresenter.getItemCount(); // 断言返回值符合预期 assertEquals(1, itemCount); }
(可选)如果需要验证size()方法的调用行为
如果你不仅要验证返回值,还想确认getItemCount()确实调用了列表的size()方法,那可以把songList转换成Spy对象(Spy可以监控真实对象的方法调用):
@Test public void testGetItemCount(){ // 创建Spy对象包装真实的songList List<Song> spySongList = spy(songList); songAdapterPresenter.setSongs(spySongList); int itemCount = songAdapterPresenter.getItemCount(); assertEquals(1, itemCount); // 现在可以用verify验证size()方法被调用了一次 verify(spySongList, times(1)).size(); }
(备选)如果无法添加setter,用反射设置私有字段
如果因为代码结构限制不能加setter,可以用PowerMock(你已经在使用PowerMockRunner)配合反射来设置私有songs字段:
@Test public void testGetItemCount() throws NoSuchFieldException, IllegalAccessException { // 反射获取私有字段 Field songsField = SongAdapterPresenter.class.getDeclaredField("songs"); songsField.setAccessible(true); // 设置字段值为测试用的songList songsField.set(songAdapterPresenter, songList); int itemCount = songAdapterPresenter.getItemCount(); assertEquals(1, itemCount); }
关键知识点总结
- 结果断言:验证方法返回值是否正确,用JUnit的
assertEquals、assertTrue等断言方法; - 行为验证:验证某个Mock/Spy对象的方法是否被调用、调用次数等,用Mockito的
verify方法; verify()的参数必须是Mock或Spy对象,不能是普通对象、基本类型值或者方法调用的返回值。
内容的提问来源于stack exchange,提问作者user8412632
相关产品推荐
相关产品推荐

