我对mocking/stubbing有着非常基本的理解。
当你在测试代码中创建一个存根时,比如:
test h = mock(test);
when(h.hello()).thenReturn(10);
在源逻辑中,我有这样的代码:
test src = new test();
src.hello();
既然我已经存根了hello方法,那么存根会被调用吗?或者既然实例不同,那么它不会被存根吗?有什么方法可以截断类的所有实例吗?
您需要使用一个工厂模式,并将一个模拟工厂注入到创建实例的类中。
因此,如果您想为某个类Foo
编写测试,该类需要在其代码中的某个位置创建Bar
的实例,则需要将BarFactory
注入到Foo
中。注入可以以老式的方式进行,将BarFactory
传递到构造函数或set方法中,或者使用像Guice这样的依赖注入框架。老式方式的一个简单例子:
class Foo {
private final BarFactory mFactory;
public Foo(BarFactory factory) {
mFactory = factory;
}
public void someMethodThatNeedsABar() {
Bar bar = mFactory.create();
}
}
现在,在您的测试类中,您可以注入一个模拟的BarFactory
,它可以生成Bar
:的模拟实例
Bar mockBar = mock(Bar.class);
BarFactory mockFactory = mock(BarFactory.class);
when(mockFactory.create()).thenReturn(mockBar);
Foo objectForTest = new Foo(mockFactory);
编写可测试代码的更好方法不是通过类代码中的新运算符创建协作类,而是将协作类作为构造函数参数传递。
class TestedClass{
private final Helper helper;
public TestedClass(Helper helper){
this.helper = helper;
}
public aMethodUsesHelper(){
//hello is weird name for method that returns int but it is link to your code
int aVar =this.helper.hello();
// ...
}
// ...
然后在测试班:
Helper helper = mock(Helper.class);
when(helper.hello()).thenReturn(10);
TestedClass tested = new Tested(helper);
// ...
您需要使用模拟实例来使存根工作。干杯:)