Cha*_*lie 50
我不知道其他好处,但我想解决你的两个子问题(这对评论来说太长了):
允许在没有依赖注入的情况下进行模拟 - 这一点对我来说并不清楚.你能详细说说吗?
我认为这来自Motivation wiki页面,它描述了一种重构代码的方法,即不调用静态方法使其可测试.对于我认为他们正在进行的具体示例,假设你有这个代码,并且你想测试模拟静态方法行为的方法,而不使用powermock:
public class MyClass {
public void doGetString() {
...
OtherClass.getString(); //It's complex and scary and needs mocking!
...
}
}
Run Code Online (Sandbox Code Playgroud)
一种解决方案是将静态调用拉入其自己的对象,然后注入一个可以在测试时进行模拟的对象.例如,不使用其他框架,这可能看起来像:
public class MyClass {
public static class StringGetter {
public getString() {
return OtherClass.getString();
}
}
private final StringGetter getter;
//Existing Constructor
public MyClass() {
this(new StringGetter());
}
//DI Constructor
MyClass(StringGetter getter) {
this.getter = getter;
}
public void doGetString() {
...
getter.getString();
...
}
}
Run Code Online (Sandbox Code Playgroud)
我已经从静态调用的行为中分离了我的方法的行为,并且可以使用DI构造函数在测试时轻松地注入模拟.当然,对于powermock,我可以在适当的位置模拟静态方法,然后运行它.
使用PowerMock时是否需要牺牲一些东西?
身体上没有,但我会说哲学上是的:).以下是我的意见,我试图在他们背后给出充分的理由,但当然他们是意见所以请他们带着一点点盐:
PowerMock发生的潜在可怕事情是,为了完成模拟私有和静态方法的壮举,他们使用自定义类加载器(在生产中不应该出现在运行时)并更改类的字节码.可以说,大多数时候这对绝大多数类来说无关紧要,但是如果你考虑一下,如果字节码发生了变化,并且某些副作用不再存在,你就可以根据你的不同来有效地测试不同的类了.现有的类.是的,这是一个非常学术性的论点.
通过良好的全面集成和不使用PowerMock的更高级别测试,您可以在某种程度上缓解第一个论点.通过这种方式,即使您的单元测试使用的是PowerMock,您也可以对对象的行为更有信心.
我对PowerMock的另一个论点是,它几乎可以轻易成为拐杖.我同意PowerMock可以帮助测试使用遗留代码的代码以及您无法控制的其他代码.但是我会争辩说,当你控制你需要模拟的类时,你应该避免使用它.如果你用私有方法或静态方法编写一个类,你需要显式模拟以测试其他方法,我的直觉就是说这个方法可能做得太多,应该重构和分解.让PowerMock在项目中已经可用,你可能会想要嘲笑它并继续前进,这将减轻应该鼓励你重构的痛苦.是的,有时由于各种技术和非技术限制这是不可能的,但是解决痛点而不是避免它们是好的:)