如何在Mockito中全局模拟方法调用?

5

我需要全局模拟类方法。

我的意思是,我不能创建模拟对象和存根方法。我的API不接受这个对象作为参数,所以我无法将其传递到函数调用中,但是这个类的对象在那些函数内部被创建并在那里使用。这就是为什么我需要全局模拟它。

class A {
  public void methodA() {}  
}

我需要模拟方法 methodA()。

我可以想象使用 mockito 实现可能是非常困难的。有人有实现这个的想法吗?或者我应该重写我的代码?


你的表述不够清晰。"global"是什么意思?你需要做什么具体的事情?使用"mock()"调用创建一个类的模拟实例,并使用"when()"的变化来限制该模拟实例的方法行为。我想你已经知道了这些,那么你的问题到底是什么?也许你应该展示更多的代码? - David M. Karr
1
你应该重构你的代码,这样它就不会在方法内部创建新的对象。这里有一些关于如何做到这一点的想法:https://code.google.com/p/mockito/wiki/MockingObjectCreation。 - Dawood ibn Kareem
重构是更好的选择,例如可以引入一个“工厂”。如果无法实现或成本过高,则可以尝试使用PowerMock。 - gontard
@DavidM.Karr “global”意味着,对于该类的每个实例都要模拟此方法,而不仅仅是使用mockito静态方法创建的一个实例。我认为我应该避免在方法内部深入创建对象,这可能会解决我的问题,感谢您的建议。 - Kasper Ziemianek
谷歌关于MockingObjectCreation的文档非常有启发性。感谢@Dawood ibn Kareem。 - whitehat
@whitehat - 没问题。顺便说一下,这不是谷歌的文档,而是Mockito团队的文档。谷歌只是为我们托管它。我是那份文件的主要作者,尽管我认为自从我第一次写它以来,Mockito团队的其他成员已经对它进行了一些调整。 - Dawood ibn Kareem
2个回答

0

在单元测试中,可以在@Before方法中仅存根调用。但您可能需要重构代码。工厂似乎很明智,您可以注入该工厂并使用下面相同的技巧将其为整个测试类存根。

@Before public void stub_sessionService_userId() {
  given(sessionService_mock.userId()).willReturn(73L);
}

0

你应该重写你的代码。

你写道:

这个类的对象在那些函数内部被创建并在那里使用

如果你想要一个可测试的系统,这通常是一个不好的做法。你提到的函数不应该自己创建对象,实际上它们甚至不应该知道对象来自哪里或者谁提供了那个对象。

更好的方法是让这些函数使用接口。该接口的实现者将成为函数的参数或注入到该函数所属的对象中,例如通过构造函数。

关于这些问题,请阅读控制反转依赖注入。这些概念对于维护模块化和可测试的系统至关重要。许多应用程序开发框架提供了必要的工具来使用依赖注入开发应用程序。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接