Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/193.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android MVP模式。将所有演示者';演示者的构造函数中的依赖项?_Android_Dependency Injection_Mvp_Dagger 2 - Fatal编程技术网

Android MVP模式。将所有演示者';演示者的构造函数中的依赖项?

Android MVP模式。将所有演示者';演示者的构造函数中的依赖项?,android,dependency-injection,mvp,dagger-2,Android,Dependency Injection,Mvp,Dagger 2,我希望我的代码是可测试和灵活的,我无法选择是需要将所有依赖项显式传递给演示者的构造函数,还是最好只将视图接口传递给构造函数并将所有依赖项注入其中。这是一种理想的模式 每次访问对象构造函数时,都应该在构造函数或其他方法中注入依赖项@Inject注释主要用于对象内部,而不是由您创建的对象 当在构造函数中注入所有依赖项时,在测试期间,您会在初始化期间将所有依赖项传递给您的模型。因此,每个测试可能包含不同的依赖项和所创建类的不同实例。这也是单元测试的目的——为每个测试提供一个沙箱 使用Mockito模拟

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

这是一种理想的模式

每次访问对象构造函数时,都应该在构造函数或其他方法中注入依赖项
@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());
    }
}
@RunWith(MockitoJUnitRunner.class)
公共类GetAreasUseCaseTest{
@模拟ApiManager和mApiManager;
@模拟数据库管理器mDatabaseManager;
私有GetArea用例管理器用例;
@统治
公共最终RxSchedulersOverrideRule moverrideschedulerRule=新RxSchedulersOverrideRule();
@以前
公共作废设置(){
mGetAreasUseCase=新的GetAreasUseCase(mApiManager,
mDatabaseManager);
doReturn(Observable.empty())
.when(mDatabaseManager)
.插入区域(任何(区域类));
}
@试验
public void testGetAreasUseCaseApiInteraction()引发异常{

TestSubscriber这是一种不错的做法,但在以后的更改中很难更改代码。如果您想为presenter添加新的依赖项,该怎么办?那么您必须更改代码中的几乎所有内容

实际上,您要做的是依赖项注入,最佳实践是进行依赖项注入,即使用Dagger之类的库

我认为Dagger是迄今为止最强大的依赖项注入库。您将编写一些方法来提供依赖项,Dagger将在您需要时使用@inject注释为您提供这些依赖项。有关完整的说明,请参阅以下链接:


非常感谢您的回答!如果您的应用程序中的所有用例都有一个基本用例,并且您需要向其添加一个新的依赖项,那么您必须更改其所有子类和许多模块以提供新的依赖项,这可能会有一个小缺点。是的,我知道。恐怕我的问题被误解了。我的意思是它是g吗ood提供依赖项作为构造函数参数,或者最好是没有任何参数的构造函数,并使用组件注入所有依赖项。注入(这)?最好使用Dagger进行所有注入,因为我告诉过你(添加依赖项时,你需要更改所有代码).Dagger将为您生成所有这些代码,如果发生更改,则不需要更改太多代码。即使从性能角度来看,向构造函数添加更多变量也会导致开销,这是不好的。不要在构造函数中发送依赖项!!那么模拟依赖项进行测试呢?使用这种方法很困难吗?w使用dagger+mvp+Reformation+mockito,您可以轻松模拟依赖项。您可以通过在新模块中提供模拟接口来模拟改装接口,而不是通过主模块提供改装接口。有关我和我的朋友制作的一个很好的示例,请参阅下面的链接: