Mockito 用 Spring 模拟:“传递给 verify() 的参数不是模拟!”

Posted

技术标签:

【中文标题】Mockito 用 Spring 模拟:“传递给 verify() 的参数不是模拟!”【英文标题】:Mockito mocks with Spring: "Argument passed to verify() is not a mock!" 【发布时间】:2010-10-05 20:53:10 【问题描述】:

我使用来自 this blog 的代码在我的单元测试中注入 Mockito 模拟。但是,在模拟自动装配之前,它会被 Spring 包装在 JDK 代理中。这会导致任何 verify(autowiredMock) 抛出 “传递给 verify() 的参数不是模拟!”。当 Mockito 检查传递给 verify(..) 的参数是否是此方法中有效的 Mockito 模拟对象时,将引发异常:

private static Method getCallbacksSetter(Class type, String methodName) throws NoSuchMethodException 
    return type.getDeclaredMethod(methodName, new Class[] Callback[].class );

我的问题是如何告诉 Spring 不要代理我在 BeanFactoryPostProcessor 中注册的 Mockito 模拟 bean?请注意,我想避免设置 proxy-target-class="true"。

谢谢

【问题讨论】:

好吧,proxy-target-class 是唯一的方法——你为什么要避免它? 因为 CJLIB 要求接口实现类具有可访问的无参数构造函数,而我的大多数类都有私有的无参数或自动装配的多参数构造函数。 【参考方案1】:

如果你将 mock 自动装配到一个 setter 方法中,你可以在那里手动解开它。

@Autowired public setMockedService(MyServiceInterface service) 
    mockedService = unwrapped(service) // to implement unwrapped(), you might use AOPUtils

虽然丑,但是没有proxy-target-class也是一种出路

顺便说一句,如果嘲笑让您如此痛苦,您不应该寻找存根解决方案吗?

【讨论】:

【参考方案2】:

最新版本的 Mockito(当前为 1.9.0)已修复此问题,更改了检测对象是否为模拟对象的算法。

【讨论】:

以上是关于Mockito 用 Spring 模拟:“传递给 verify() 的参数不是模拟!”的主要内容,如果未能解决你的问题,请参考以下文章

用于 PC Mockito 模拟验证的自定义 Hamcrest 匹配器

如何使用 Mockito 在 Spring 中模拟自动装配的 @Value 字段?

使用 Spring Boot 和 Mockito 模拟对象方法调用

Kotlin,Spring book,Mockito,@InjectMocks,使用与创建的不同的模拟

JUnit、Mockito 和 Spring ApplicationContext:模拟属性时遇到问题

Spring 集成框架中 ResponseEntity<?> 的 Junit Mockito 测试用例