Mockito中如何为嵌套值使用any或anyNamed匹配器?
解决Mockito嵌套对象参数匹配的问题
你遇到的问题其实是Mockito参数匹配器的使用限制导致的——匹配器(比如anyNamed、any)只能作用于被Mock方法的直接参数,不能直接嵌套在你创建的对象(比如RequestOptions)内部。
为什么会报错?
你写的代码里,把anyNamed("method")放在了RequestOptions的method参数里,这相当于你主动创建了一个RequestOptions对象,而Mockito的匹配器是用来匹配传给adapterMock.fetch的参数的,不是用来填充对象属性的。报错信息里的提示也明确了:匹配器必须作为被Mock方法的命名参数传递,而不是嵌套在对象内部。
正确的解决方案:使用argThat自定义匹配器
要匹配嵌套对象的属性,你需要用argThat来创建一个自定义的匹配逻辑,检查传入的RequestOptions对象是否符合你的预期。
举几个常见场景的例子:
场景1:匹配path为"orders",不管method是什么
when(adapterMock.fetch( argThat((RequestOptions opts) => opts.path == "orders"), any, any, )).thenAnswer((_) async => response);
场景2:同时匹配path和method
如果你需要同时校验method和path,可以扩展匹配逻辑:
when(adapterMock.fetch( argThat((RequestOptions opts) => opts.path == "orders" && opts.method == "GET"), any, any, )).thenAnswer((_) async => response);
场景3:匹配method为任意字符串类型
如果想让method匹配任意有效的字符串值,可以用类型检查:
when(adapterMock.fetch( argThat((RequestOptions opts) => opts.path == "orders" && opts.method is String), any, any, )).thenAnswer((_) async => response);
补充说明
argThat的闭包会接收实际传给fetch的RequestOptions对象,你可以在闭包里写任何你需要的校验逻辑,非常灵活。- 如果你之前用
anyNamed是想标记某个参数的语义,在嵌套场景下,直接在argThat的逻辑里明确校验规则就可以达到同样的效果。
内容的提问来源于stack exchange,提问作者Limbou
相关产品推荐
相关产品推荐

