有什么方法可以使用 mockito 模拟静态方法吗?
Are there any ways to mock static methods using mockito?
我想为我的更改编写测试,但遇到了问题 - 更改是在静态方法中进行的。
代码看起来像这样
class GlobalData {
static boolean doSomething(...){...}
static xxx A() {...}
static yyy B() {...}
static void C() {
xxx a = A();
yyy b = B();
if (doSomething(a, b))
{
a.xyz(b,42);
... my coode i want to test....
}
}
我想要的是模拟方法 A 和 B 以及 doSomething 以及方法 C 中使用的所有这些静态方法,但目前我找不到任何方法来做到这一点。你现在有吗?
因为你不能覆盖静态方法,不,你不能在 Mockito 中模拟它们。
您should/could使用单例模式。
基本上所有的静态方法都会调用一个内部私有对象来执行实际逻辑(称为 实例)。
如果这样做,您可以提供一个受保护的静态方法setInstance
。在测试期间,您创建了一个模拟的 实例 并将其设置为静态 class.
这是可行的,但它不是最优雅的解决方案,但静态调用首先并不是那么优雅。我正在回答,因为无法重构整个代码库(例如使用 Dependency Injection)
例如:
class GlobalData {
//private object that does all the actual logic
private static GlobalData instance = new GlobalData();
//constructor is private so no one can call it
private GlobalData() {
}
//delegate the static call to the internal instance
static boolean doSomething(...){ return instance._doSomething(); }
//use underscore to keep similar name but avoid ambiguous call
private boolean _doSomething(...){ ... }
//same here
static xxx A() { return instance._A(); }
private xxx _A() {...}
//this is not public, so must be called from the same package
//since the constructor is private, no one will be able to create a GlobalData
//except for mockito
static void setInstance(GlobalData instance) {
GlobalData.instance = instance;
}
}
然后在你的测试中(应该在同一个包中):
GlobalData instanceMocked = mock(GlobalData.class);
//we mock the methods with underscore, as they are the instance methods, and
//not the class methods
when(instanceMocked._A()).thenReturn(whatever);
when(instanceMocked._doSomething()).thenReturn(whatever);
GlobalData.setInstance(instanceMocked);
这只需要对您正在查看的 class 进行少量重构,而无需触及项目的其余部分,同时实现您想要的。
考虑使用 powerMock。它在 Mockito 上有一个名为 'powerMockito' 的扩展。它还使您能够模拟静态方法。
https://github.com/jayway/powermock/wiki/MockitoUsage
我想为我的更改编写测试,但遇到了问题 - 更改是在静态方法中进行的。 代码看起来像这样
class GlobalData {
static boolean doSomething(...){...}
static xxx A() {...}
static yyy B() {...}
static void C() {
xxx a = A();
yyy b = B();
if (doSomething(a, b))
{
a.xyz(b,42);
... my coode i want to test....
}
}
我想要的是模拟方法 A 和 B 以及 doSomething 以及方法 C 中使用的所有这些静态方法,但目前我找不到任何方法来做到这一点。你现在有吗?
因为你不能覆盖静态方法,不,你不能在 Mockito 中模拟它们。
您should/could使用单例模式。
基本上所有的静态方法都会调用一个内部私有对象来执行实际逻辑(称为 实例)。
如果这样做,您可以提供一个受保护的静态方法setInstance
。在测试期间,您创建了一个模拟的 实例 并将其设置为静态 class.
这是可行的,但它不是最优雅的解决方案,但静态调用首先并不是那么优雅。我正在回答,因为无法重构整个代码库(例如使用 Dependency Injection)
例如:
class GlobalData {
//private object that does all the actual logic
private static GlobalData instance = new GlobalData();
//constructor is private so no one can call it
private GlobalData() {
}
//delegate the static call to the internal instance
static boolean doSomething(...){ return instance._doSomething(); }
//use underscore to keep similar name but avoid ambiguous call
private boolean _doSomething(...){ ... }
//same here
static xxx A() { return instance._A(); }
private xxx _A() {...}
//this is not public, so must be called from the same package
//since the constructor is private, no one will be able to create a GlobalData
//except for mockito
static void setInstance(GlobalData instance) {
GlobalData.instance = instance;
}
}
然后在你的测试中(应该在同一个包中):
GlobalData instanceMocked = mock(GlobalData.class);
//we mock the methods with underscore, as they are the instance methods, and
//not the class methods
when(instanceMocked._A()).thenReturn(whatever);
when(instanceMocked._doSomething()).thenReturn(whatever);
GlobalData.setInstance(instanceMocked);
这只需要对您正在查看的 class 进行少量重构,而无需触及项目的其余部分,同时实现您想要的。
考虑使用 powerMock。它在 Mockito 上有一个名为 'powerMockito' 的扩展。它还使您能够模拟静态方法。 https://github.com/jayway/powermock/wiki/MockitoUsage