在这个情况下?
class A {
public void f() {
B b = new B();
C c = new C();
// use b and c, and how to modify their behaviour?
}
}
我怎样才能用PowerMock
and来完成我的想法EasyMock
?
出于测试原因,我不想更改我的紧凑代码。
事实上,您可以使用 PowerMock 模拟对象构造。他们在这里有很好的文档:https ://code.google.com/p/powermock/wiki/MockConstructor
还请看一下这个示例,该示例介绍了模拟对象的构造。
您可以这样做,请参阅 Matt Lachman 的答案。但是不推荐这种方法。这有点骇人听闻。
最好的方法是将依赖对象的创建委托给工厂模式并将工厂注入到您的A
类中:
class BFactory {
public B newInstance() {
return new B();
}
}
class CFactory {
public C newInstance() {
return new C();
}
}
class A {
private final BFactory bFactory;
private final CFactory cFactory;
public A(final BFactory bFactory, final CFactory cFactory) {
this.bFactory = bFactory;
this.cFactory = cFactory;
}
public void f() {
B b = bFactory.newInstance();
C c = cFactory.newInstance();
}
}
然后,您将模拟工厂以返回依赖类的模拟实例。
如果由于某种原因这不可行,那么您可以在A
类中创建工厂方法
class A {
public void f() {
B b = newB();
C c = newC();
}
protected B newB() {
return new B();
}
protected C newC() {
return newC();
}
}
然后您可以使用spy
模拟这些工厂方法的 a 。
看起来你需要依赖注入。
您正在创建B 和 C 的具体实例,然后您无法修改行为。
将实例作为参数传递给f(InterfaceB b, InterfaceC c)
,您应该使用多态性,然后您可以将需要更改其行为的模拟实例作为参数传递给此方法。因此,该方法不需要关心它传递给它的具体实例类型,您可以实现您所需要的。
我知道接口的名称是不合逻辑的,但这可以很容易地解释上下文。
如果不更改代码,它将无法正常工作。(可测试性设计)。您可以将 B 替换为工厂方法,该方法在实际中创建 B1 或在测试中创建 BTest,两者都实现了 IB 接口。