我正在使用Mockito 1.9.0 . 我想在JUnit测试中模拟一个类的单个方法的行为,所以我有
final MyClass myClassSpy = Mockito.spy(myInstance);
Mockito.when(myClassSpy.method1()).thenReturn(myResults);
问题是,在第二行, myClassSpy.method1()
实际上被调用,导致异常 . 我使用模拟的唯一原因是,以后,每当调用 myClassSpy.method1()
时,将不会调用真实方法并返回 myResults
对象 .
MyClass
是一个接口, myInstance
是一个实现,如果这很重要 .
我需要做些什么来纠正这种 Spy 行为?
7 回答
我发现了 Spy 调用原始方法的另一个原因 .
有人有想法嘲笑一个
final
类,并发现MockMaker
:资料来源:https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2#mock-the-unmockable-opt-in-mocking-of-final-classesmethods
合并并将该文件带到我的机器后,我的测试失败了 .
我只需删除行(或文件),
spy()
工作 .让我引用the official documentation:
在你的情况下它是这样的:
我的案子与接受的答案不同 . 我试图为一个没有存在于该包中的实例模拟一个包私有方法
和测试类
编译是正确的,但是当它尝试设置测试时,它会调用实际方法 .
声明方法受到保护或公开修复问题,这不是一个干净的解决方案 .
可能导致 Spy 问题的另一种可能情况是,当您测试 spring beans (使用 spring 测试框架)或其他一些 framework that is proxing your objects during test 时 .
例
在上面的代码中,Spring和Mockito将尝试代理您的MonitoringDocumentsRepository对象,但Spring将是第一个,这将导致findMonitoringDocuments方法的真实调用 . 如果我们在将一个 Spy 放在存储库对象之后调试我们的代码,它将在调试器中看起来像这样:
@SpyBean to the rescue
如果改为
@Autowired
注释我们使用@SpyBean
注释,我们将解决上面的问题,SpyBean注释也将注入存储库对象,但它将首先由Mockito代理并在调试器中看起来像这样这是代码:
The answer by Tomasz Nurkiewicz appears not to tell the whole story!
NB Mockito版本:1.10.19 .
我非常喜欢Mockito newb,所以无法解释以下行为:如果有专家可以改进这个答案,请随意 .
这里讨论的方法
getContentStringValue
是 NOTfinal
和 NOTstatic
.这行 does 调用原始方法
getContentStringValue
:这行 does not 调用原始方法
getContentStringValue
:由于我无法回答的原因,使用
isA()
会导致doReturn
的预期(?)"do not call method"行为失败 .让我们看一下这里涉及的方法签名:它们都是
Matchers
的static
方法 . Javadoc都说两者都返回了null
,这本身就有点难以理解 . 据推测,作为参数传递的Class
对象被检查但结果要么从未计算过,要么被丢弃 . 鉴于null
可以代表任何类,并且你希望不被调用的模拟方法,isA( ... )
和any( ... )
的签名只能返回null
而不是通用参数*<T>
?无论如何:
API文档没有提供任何关于此的线索 . 它似乎也表示需要这样的"do not call method"行为是"very rare" . 我个人使用这种技术 all the time :通常我发现嘲讽涉及几行"set the scene" ...然后调用一个方法,然后在你上演的模拟上下文中的场景......当你设置风景时道具你想要的最后一件事就是让演员们进入舞台并开始表现他们的心灵......
但这超出了我的工资等级...我邀请任何通过Mockito高级牧师的解释......
*是“通用参数”的正确用语吗?
在我的例子中,使用Mockito 2.0,我必须将所有any()参数更改为nullable()以便存根真实的调用 .
确保未调用类中的方法的一种方法是使用哑元覆盖该方法 .