使用dagger 2创建对象的单元测试类

时间:2016-11-04 01:34:50

标签: unit-testing dagger-2

假设我有一个匕首2模块如下,

@Module
interface Creator {
    MyClass create();
}

我用它来创建MyClass的实例

class Instantiator {
    void doSomething(){
        MyClass clazz = DaggerCreator.create().create();
        // do things with clazz

    }
}

在我看来,我无法在Instantiator中有效地测试doSomething方法,因为我无法为MyClass提供模拟。

我错了吗?如果不是,我们应该谨慎地使用Dagger实例化吗?

1 个答案:

答案 0 :(得分:1)

你说的是很难测试Component注入器的使用,因为这是一种静态方法。但比什么更难?这是使用实例化的相同方法:

class Instantiator {
    void doSomething(){
        MyClass clazz = new MyClass();
        // do things with clazz

    }
}

仍然难以测试,对吧?

关键是尽可能少地使用Component(注入器)并在对象的构造函数中传递依赖关系。 Dagger 2使得构造函数中的依赖项变得容易。这样可以简化测试,因为您可以在构造函数中传递模拟对象。

让我们重构您编写的可测试代码。假设MyClass包含单个方法,fireLazers() Instantiator方法中正在调用您要测试的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();
    }

}