Unit testing 使用dagger 2创建对象的单元测试类
假设我有一个匕首2模块,如下所示Unit testing 使用dagger 2创建对象的单元测试类,unit-testing,dagger-2,Unit Testing,Dagger 2,假设我有一个匕首2模块,如下所示 @Module interface Creator { MyClass create(); } 我用它来创建MyClass的一个实例 class Instantiator { void doSomething(){ MyClass clazz = DaggerCreator.create().create(); // do things with clazz } } 在我看来,我无法在实例化器中有效地
@Module
interface Creator {
MyClass create();
}
我用它来创建MyClass的一个实例
class Instantiator {
void doSomething(){
MyClass clazz = DaggerCreator.create().create();
// do things with clazz
}
}
在我看来,我无法在实例化器中有效地测试doSomething方法,因为我无法为MyClass提供模拟
我错了吗?如果不是的话,我们应该少用Dagger实例化吗?你说很难测试
组件的使用,这是正确的,因为这是一种静态方法。但比什么更难?下面是使用实例化的相同方法:
class Instantiator {
void doSomething(){
MyClass clazz = new MyClass();
// do things with clazz
}
}
还是很难测试,对吗
关键是使用尽可能少的组件
(注入器),并在对象的构造函数中传递依赖项。Dagger 2使解析构造函数中的依赖项变得容易。这使得测试变得容易,因为您可以在构造函数中传入模拟对象
让我们重构您编写的可测试代码。假设MyClass
包含一个方法,fireLazers()
要测试的方法正在实例化器的doSomething()方法中调用:
public class DoerOfSomething {
private final MyClass myClass;
@Inject
public DoerOfSomething(MyClass myClazz) {
this.myClass = myClazz;
}
public void doSomething() {
myClass.fireLazers();
}
}
现在,您可以使用模拟对象编写如下测试:
public void DoerOfSomethingTest {
//mocks
MyClass mockMyClass;
//system under test
DoerOfSomething doerOfSomething;
@Before
public void setUp() {
mockMyClass = Mockito.mock(MyClass.class);
}
@Test
public void whenDoSomething_thenInteractsWithMyClass() {
//arrange
doerOfSomething = new DoerOfSomething(mockMyClass);
//act
doerOfSomething.doSomething();
//assert
verify(mockMyClass).fireLazers();
}
}
当然,您现在需要将DoerOfSomething
注入到您注入的顶级类中,但是现在您可以确定您注入的对象按预期运行,因为它是可测试的。您使用Dagger的代码看起来有点不寻常,但为了在问题和答案之间保持平衡,我将使用您的习惯用法
class Instantiator {
private final DoerOfSomething doerOfSomething;
Instantiator() {
doerOfSomething = DaggerCreator.create().create();
}
void doSomething() {
doerOfSomething.doSomething();
}
}
有道理。我担心的是,在一个类中实例化一个远离对象图根的对象会使单元测试变得困难,但正如您所说的,这个问题并不会消失。我想我能做的另一件事是注入ObjectCreator本身,我认为这是可能的,但我需要尝试一下。