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

Mockito验证ArrayList大小:无视图时如何验证getItemCount方法?

解决Mockito验证getItemCount时的NotAMockException问题

你遇到的NotAMockException是因为用错了Mockito的verify()方法——它可不是用来断言返回值的,而是用来验证Mock/Spy对象的方法调用行为的,而你把一个普通int值(songList.size()的结果)传给了verify(),这完全不符合它的用法。

咱们一步步来修复这个问题:

首先搞清楚问题根源

你的SongAdapterPresenter.getItemCount()逻辑是返回songs列表的长度,但当前测试里有两个核心问题:

  1. 测试用的songList根本没传给SongAdapterPresenter,所以它内部的songs还是null,调用getItemCount()只会返回0;
  2. 用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:24:48