2

使用dagger2注入依赖关系到espresso测试是我想要做的。Android咖啡 - 如何使用dagger2注入依赖关系

我想要一种能够为我的测试用例使用匕首提供依赖性的方法。

特别是有一个MockwebServer类我想用匕首注入。这是如何完成的? 我的项目已经设置了匕首。其目前和单componeent单一成分有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文件夹做一个咖啡怎么考,我会使用以下组件:

//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类传递后改造为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的参考,并在我的测试中使用它,并有它的改造工作,所以我可以做快速集成测试

也gradle我使用以下依赖关系,请确认:

compile 'com.google.dagger:dagger:2.9' 
testCompile 'com.google.dagger:dagger:2.9' 
annotationProcessor 'com.google.dagger:dagger-compiler:2.9' 

回答

6

我将试图解释如何做到这一点:

在您的应用程序类,你应该有指定的应用程序组件,它包含您的API服务:

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测试包:

现在,您需要创建延伸,你有你的匕首组件初始化应用程序类新的应用程序类。

因此,现在您可以覆盖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。创建其指向新app类新转轮

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); 
}} 
  • 声明哪些转轮将在build.gradle被使用。
  • testInstrumentationRunner ".MockTestRunner"

    完蛋了。现在您的请求将使用模拟的响应! 如果您有任何问题,请询问。

    干杯

    +0

    这很好。我通过为匕首创建一个重复的测试组件并使用匕首模拟来使用该测试组件来实现它。你的更好 – j2emanue

    +0

    谢谢,我很高兴听到它:) –