Android espresso - 如何使用 dagger2 注入依赖
Android espresso - how to use dagger2 to inject dependencies
使用 dagger2 将依赖项注入 espresso 测试是我想要做的。
我想要一种能够使用 dagger 为我的测试用例提供依赖项的方法。
特别是 MockwebServer class 我想用匕首注射。这是怎么做到的?
我的项目已经设置了匕首。它现在是一个组件,单个组件有 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?
我想注入我的 class 的原因是我想在将 mockWebServer class 传递给像这样的 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'
我将尝试解释如何操作:
在您的应用程序 class 中,您应该指定包含 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 测试包中:
现在,您需要创建新的应用程序 class 来扩展您的应用程序 class,您在其中进行了 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
class 应该用于测试。
现在你还需要做两件事:
1. 创建新的runner指向新的App Class
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"
就是这样。现在您的请求将使用模拟响应!
如果您有任何问题,请直接提问。
干杯
使用 dagger2 将依赖项注入 espresso 测试是我想要做的。
我想要一种能够使用 dagger 为我的测试用例提供依赖项的方法。
特别是 MockwebServer class 我想用匕首注射。这是怎么做到的? 我的项目已经设置了匕首。它现在是一个组件,单个组件有 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?
我想注入我的 class 的原因是我想在将 mockWebServer class 传递给像这样的 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'
我将尝试解释如何操作:
在您的应用程序 class 中,您应该指定包含 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 测试包中:
现在,您需要创建新的应用程序 class 来扩展您的应用程序 class,您在其中进行了 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
class 应该用于测试。
现在你还需要做两件事:
1. 创建新的runner指向新的App Class
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"
就是这样。现在您的请求将使用模拟响应! 如果您有任何问题,请直接提问。
干杯