安卓Espresso - 如何使用Dagger2注入依赖项

4

使用dagger2向espresso测试注入依赖项是我想要做的。

我希望能够使用dagger为我的测试用例提供依赖项的方法。

特别是,我想使用dagger注入MockwebServer类。如何实现?我的项目已经设置了dagger。目前只有一个组件,该组件有5个模块,看起来像这样:

@Singleton
@Component(modules = {AppModule.class, NetworkModule.class, RepositoryModule.class, UseCaseModule.class, ActivityModule.class, PresenterModule.class})
public interface AppComponent {

    void inject(NetworkSessionManager target);
    void inject(SplashActivity target);
    void inject(AuthenticationActivity target);
    void inject(WelcomeActivity target);
    void inject(LoginFragment target);
}

它很好用。但是现在当我移动到androidTest文件夹进行Espresso测试时,我该如何使用以下组件:

    //note the NetworkTestModule.class i want to use is defined instead of //networkModule.class
        @Singleton
        @Component(modules = {AppModule.class, NetworkTestModule.class, RepositoryModule.class, UseCaseModule.class, ActivityModule.class, PresenterModule.class})
        public interface AppTestComponent

 {

        void inject(NetworkSessionManager target);
        void inject(SplashActivity target);
        void inject(AuthenticationActivity target);
        void inject(WelcomeActivity target);
        void inject(LoginFragment target);
        void inject (MYTESTCLASS target);
    }

我会尽力为您翻译中文。这篇文章与编程有关,作者保留了AppTestComponent的主要源代码,但这种方式无法看到MYTESTCLASS。我想注入我的类,是因为我想将mockWebServer类传递给Retrofit作为baseurl,以此来进行注入。

TestNetworkModule.java:

@Provides
@Singleton
public Retrofit provideRetrofit(Converter.Factory converter, OkHttpClient client, @Named(BASE_URL) String baseUrl, MockWebServer server) {
    return new Retrofit.Builder()
            .baseUrl(server.url("/").toString())
            .client(client)
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(converter)
            .build();
}

    @Singleton
    @Provides
    MockWebServer providerMockWebServer() {
        return new MockWebServer();
    }
    //....
    }

这样我就可以在我的测试中获得 MockWebServer 的引用,并使用它让 Retrofit 与之配合,以便进行快速的集成测试。请注意,保留 HTML 标签。
另外,在 Gradle 中我正在使用以下依赖项,请确认:
 compile 'com.google.dagger:dagger:2.9'
testCompile 'com.google.dagger:dagger:2.9'
annotationProcessor 'com.google.dagger:dagger-compiler:2.9'
1个回答

11

我将尝试解释如何做:

在你的应用程序类中,你应该已经指定了包含 API 服务的 Application 组件:

protected AppComponent initializeAppComponent() {
    return DaggerAppComponent.builder()
            .apiServiceModule(new APIServiceModule(this))
            .otherModules(new otherModules(this))
            .build();
}

像这样注入:

@Override
public void onCreate() {
    applicationComponent = initializeAppComponent();
    applicationComponent.inject(this)}};

这是标准的初始化程序。您只需将组件构建器移动到稍后可以重写的方法中。

在您的Android测试包中:

现在,您需要创建一个新的应用程序类,该类扩展了您的应用程序类,在其中进行Dagger组件初始化。

因此,现在您可以重写initializeAppComponent()方法,并通过扩展先前模块的新模块切换您的APIServiceModule。 它应该看起来像这样:

public class MockApp extends App {

@Override
protected AppComponent initializeAppComponent() {
    return DaggerAppComponent.builder()
            .apiServiceModule(new MockAPIServiceModule(this))
            .otherModules(new OtherModules(this))
            .build();
}

@Module
private class MockAPIServiceModule extends APIServiceModule {

    @Override
    public ApiService provideApiService(@Nonnull final Retrofit retrofit,
                                        @Nonnull final Gson gson) {
        return new ApiService() {
            @Override
            public Observable<LoginResponse> login(@Body final LoginRequest loginRequest) {
                return // what you want to
            }
        }
    }
}}

您需要声明应该用于测试的Application类。 现在您需要完成2个步骤: 1. 创建一个指向新应用程序类的新运行器

public class MockTestRunner extends AndroidJUnitRunner{

@Override
public void onCreate(Bundle arguments) {
    StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitAll().build());
    StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().build());
    super.onCreate(arguments);
}
@Override
public Application newApplication(ClassLoader cl, String className, Context context)
        throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    return super.newApplication(cl, MockApp.class.getName(), context);
}}
  1. build.gradle文件中声明要使用哪个运行器。

testInstrumentationRunner ".MockTestRunner"

就这样。现在你的请求将使用模拟响应!如果有任何问题,请随时询问。

干杯


这很不错。我也通过创建Dagger的一个重复测试组件并使用带有Dagger模拟的测试组件来实现了它。不过你的方法更好。 - j2emanue
谢谢,我很高兴听到这个 :) - Piotr Mądry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接