MVP模式。在演示者的构造函数中注入所有演示者的依赖项是一种好习惯吗?

时间:2016-08-31 12:54:12

标签: android dependency-injection mvp dagger-2

我希望我的代码可测试且灵活,我无法选择是否需要将所有依赖项显式传递给演示者的构造函数,或者最好只将View接口传递给构造函数并在其中注入所有依赖项。

2 个答案:

答案 0 :(得分:3)

这是一种理想的模式。

每次有权访问对象构造函数时,都应该在构造函数或其他方法中注入依赖项。 @Inject注释主要用于在对象内部使用,不是由您创建的。

在构造函数中注入所有依赖项时,在测试期间,您会在初始化期间将所有依赖项传递给模型。因此,每个测试可能包含不同的依赖项和创建的类的不同实例。这也是单元测试的目的 - 为每次测试提供沙箱。

使用Mockito模拟依赖项也更容易。

请记住,在单元测试中,您不会依赖任何框架配置。单元测试通常包含已创建的模型,仅此而已。一切都必须由你创建(或由框架嘲笑)

以下是一个样本单元测试,证明了上述陈述:

@RunWith(MockitoJUnitRunner.class)
public class GetAreasUseCaseTest {
    @Mock ApiManager mApiManager;
    @Mock DatabaseManager mDatabaseManager;

    private GetAreasUseCase mGetAreasUseCase;

    @Rule
    public final RxSchedulersOverrideRule mOverrideSchedulersRule = new RxSchedulersOverrideRule();

    @Before
    public void setUp() {
        mGetAreasUseCase = new GetAreasUseCase(mApiManager,
                mDatabaseManager);
        doReturn(Observable.empty())
                .when(mDatabaseManager)
                .insertAreas(any(Area.class));
    }

    @Test
    public void testGetAreasUseCaseApiInteraction() throws Exception {
        TestSubscriber<List<Area>> testSubscriber = new TestSubscriber<>();
        setCorrectApiResponse();
        boolean input = true;
        Observable testedObservable = mGetAreasUseCase.build(input);
        testedObservable.subscribe(testSubscriber);
        verify(mApiManager).getAreas(anyLong());
    }
}

正如您所看到的,测试结构非常清晰。众所周知,被嘲笑的是什么以及测试了哪个对象。您可以控制依赖项的行为。

如果您计划仅进行检测测试,则会在测试中为您提供ApplicationContext,并且Dagger已正确初始化。这里没有区别。当然,您仍然可以模仿ModuleComponent的行为并提供自定义对象的模拟而不是真实的类(Example

答案 1 :(得分:-1)

这不是一个糟糕的做法,但很难在以后的更改中更改代码。如果您想为演示者添加新的依赖项,该怎么办?然后你必须改变代码中的几乎所有内容。

实际上你要做的事情叫做依赖注入,最好的做法是做依赖注入,使用像Dagger这样的库。

我认为Dagger是迄今为止最强大的依赖注入库。您将编写一些提供依赖项的方法,Dagger会在您希望它们使用@inject Annotation时为您提供这些方法。有关完整说明,请参阅此链接:

http://www.vogella.com/tutorials/Dagger/article.html