如何无需强制转换使用Hamcrest匹配Mockito集合参数
这问题我之前也踩过坑,强制转换不仅看着闹心,还容易埋下类型隐患。给你几个更优雅的解决方案,彻底摆脱强制转换:
方案1:用Mockito原生的argThat(推荐)
Mockito本身就提供了argThat方法,它的泛型推断比MockitoHamcrest.argThat更友好。直接结合Hamcrest的hasItem就行,完全不需要强制转换:
import static org.mockito.ArgumentMatchers.argThat; import static org.hamcrest.CoreMatchers.hasItem; // ... when(someService.doSomething(argThat(hasItem(mySomeTypeInstance)))) .thenReturn(yourMockedResultList);
方案2:显式声明Matcher变量
如果你坚持要用MockitoHamcrest.argThat,可以先把Matcher赋值给一个明确类型的变量,让编译器帮你搞定类型推断:
import static org.mockito.hamcrest.MockitoHamcrest.argThat; import static org.hamcrest.CoreMatchers.hasItem; // ... ArgumentMatcher<List<SomeType>> listMatcher = hasItem(mySomeTypeInstance); when(someService.doSomething(argThat(listMatcher))) .thenReturn(yourMockedResultList);
方案3:Java 8+ 用Lambda直接写判断
如果不想依赖Hamcrest,直接用Lambda表达式实现匹配逻辑,代码更简洁,还能自定义更复杂的判断:
import static org.mockito.ArgumentMatchers.argThat; // ... when(someService.doSomething(argThat(list -> list != null && list.contains(mySomeTypeInstance)))) .thenReturn(yourMockedResultList);
为啥原来的写法需要强制转换?
简单说,MockitoHamcrest.argThat的泛型参数T需要和方法参数类型完全匹配,而hasItem返回的是Matcher<Iterable<? super SomeType>>,编译器没法自动推断出T就是List<SomeType>,所以得手动强转。上面的方案要么利用了Mockito更智能的类型推断,要么显式指定了类型,自然就不需要强转啦。
内容的提问来源于stack exchange,提问作者androberz
相关产品推荐
相关产品推荐

