如何使用 Dagger2 将 Activity 范围内的依赖项替换为模拟

sud*_*nix 5 android unit-testing dependency-injection dagger dagger-2

我的 Activity 中有范围依赖项,我想用一些模拟来测试该 Activity。我读过有关建议在测试期间用测试组件替换应用程序组件的不同方法,但我想要的是替换活动组件。

例如,我想在 MVP 设置中针对模拟演示者测试活动。

我相信通过在 Activity 上调用 setComponent() 来替换组件是行不通的,因为 Activity 依赖项已经通过字段注入注入了,所以在测试过程中,将使用真实的对象。

我该如何解决这个问题?匕首1呢?是否有同样的问题?

Epi*_*rce 0

您不能覆盖 Dagger2 中的模块[编辑:您可以,只是不要@Provides在模拟上指定注释),这显然是正确的解决方案:只需使用builder().somethingModule(new MockSomethingModule()).build()并完成即可!

如果您认为模拟是不可能的,那么我会看到这个问题的两种可能的解决方案。您可以使用模块来包含可插入的“提供者”,可以更改其实现(我不喜欢这样做,因为它太冗长了!)

public interface SomethingProvider {
    Something something(Context context);
}

@Module
public class SomethingModule {
    private SomethingProvider somethingProvider;

    public SomethingModule(SomethingProvider somethingProvider) {
        this.somethingProvider = somethingProvider;
    }

    @Provides
    @Singleton
    public Something something(Context context) {
        return somethingProvider.something(context);
    }
}

public class ProdSomethingProvider implements SomethingProvider {
    public Something something(Context context) {
        return new SomethingImpl(context);
    }
}

public class TestSomethingProvider implements SomethingProvider {
    public Something something(Context context) {
        return new MockSomethingImpl(context);
    }
}

SomethingComponent somethingComponent = DaggerSomethingComponent.builder()
    .somethingModule(new SomethingModule(new ProdSomethingProvider()))
    .build();
Run Code Online (Sandbox Code Playgroud)

或者,您可以将提供的类和注入目标引入到它们自己的“元组件”接口中,您可以使用该接口ApplicationComponent和您的TestApplicationComponent扩展都是从该接口扩展的。

public interface MetaApplicationComponent {
    Something something();

    void inject(MainActivity mainActivity);
}

@Component(modules={SomethingModule.class})
@Singleton
public interface ApplicationComponent extends MetaApplicationComponent {
}

@Component(modules={MockSomethingModule.class})
@Singleton
public interface MockApplicationComponent extends MetaApplicationComponent {
}
Run Code Online (Sandbox Code Playgroud)

第三种解决方案是像 @vaughandroid 的答案一样扩展模块。参考一下,这才是正确的做法。

至于活动范围的组件......与我在这里提到的相同,它只是一个不同的范围,真的。