我知道Mockito不支持模拟局部变量、静态方法和私有方法。有什么办法可以绕过它吗。
与私有方法一样,将方法从私有方法更改为私有方法也可以,或者我们可以将其更改为受保护的接口,以便编写测试脚本。对于静态方法和局部变量,我们有类似的东西吗?
https://github.com/mockito/mockito/wiki/FAQ说Mockito的局限性。如果它有任何其他的限制,以及如何克服它们,我指的是重构,是否有任何Mockito大师允许我。谢谢。
发布于 2016-08-11 18:40:05
为了帮助理解Mockito的局限性,重要的是要了解Mockito为您做了什么:Mockito为您传入的类创建了一个动态的(基于代理的)子类。这意味着,就像您自己编写的子类一样,您将无法访问或控制私有字段和方法、静态方法和局部变量。没有解决办法。
您在注释中提到了PowerMock,它通过重写要模拟的类的字节码或使用要模拟的类的类来解决Mockito的一些限制。这允许PowerMock拦截无法通过多态性覆盖的调用,特别是private、static和final字段。您也无法访问局部变量。
你最好的选择是重组你的类或方法,这样它就能给你想要的控制。一般来说,您应该问“如果我创建了自己的子类,我是否能够这样做”,这个答案将有助于确定Mockito是否可以为您自动执行。
(请注意,下面我提到了“为模拟而设计的”,但您真正要做的是为您的依赖项的替代实现设计;模拟只是其中的一个例子,以及各种其他测试双倍,比如假的或内存中的实现。请记住,并不是所有的东西都需要被模拟或替换才能保持单元测试;只需确保测试中的依赖关系是快速的、确定性的和良好的测试。相反,对于缓慢、不确定、测试不佳或尚未编写的组件,用假或模拟替代实现可能会提高测试质量和覆盖率。)
public class NotDesignedForMocking {
public int yourMethod() {
Calculator calculator = new Calculator(); // impossible to mock!
return calculator.calculate();
}
}一种技术是将依赖项作为方法参数传递。
public class DesignedForMockingViaMethodLevelDependencyInjection {
public int yourMethod() {
return yourMethod(new Calculator());
}
// Call this from tests instead; you can pass in a mock.
int yourMethod(Calculator calculator) {
return calculator.calculate();
}
}另一种方法是切换到完全依赖注入:
public class DesignedForMockingViaFullDependencyInjection {
private final Calculator calculator;
public DesignedForMockingViaFullDependencyInjection() {
this(new Calculator());
}
// Create objects in your test with this, so you can pass in a mock Calculator.
DesignedForMockingViaFullDependencyInjection(Calculator calculator) {
this.calculator = calculator;
}
int yourMethod() {
return calculator.calculate();
}
}最后,您可以创建一个可覆盖的工厂方法,它引入了Mockito在基于子类的重写中所需的多态性。
public class DesignedForMockingWithOverridableFactoryMethod {
public int yourMethod() {
Calculator calculator = createCalculator();
return calculator.calculate();
}
// Create an anonymous override in your class, or use a Mockito spy to intercept
// and override the behavior.
protected Calculator createCalculator() {
return new Calculator();
}
}发布于 2016-08-11 19:30:11
避免Mockito限制的最佳方法是不要坚持编写孤立的单元测试。
与某些人所认为的相反,单元测试不需要与被测试单元的依赖关系隔离运行。正如马丁·福勒 (以及TDD的“父亲”Kent所实践的那样),单元测试可以是“社会化的”(没有对依赖关系的嘲弄)或“孤立的”(带有模拟的依赖)。
因此,避免那些嘲讽工具限制的方法之一就是根本不依赖它们。您可以通过编写“社会化”单元测试来实现这一点,或者(像我一样)一路编写集成测试。
前面提到的另一个“解决方案”是重构正在测试的代码,以绕过模拟限制,或者“设计用于嘲弄”(正如Jeff所说)。我希望大多数开发人员认识到这是一个糟糕的解决方案,因为它通常需要在SUT中增加额外的复杂性,以弥补特定的模拟库中的任意限制。考虑增加private方法的可访问性的情况,这样就可以直接测试或模拟它。那么,如果您认为这是可以接受的,那么您真的关心代码质量吗?如果你不在乎,那你为什么还要费心于自动化的开发人员测试呢?
https://stackoverflow.com/questions/38899562
复制相似问题