Android测试:使用Dagger2 + Gradle [英] Android Tests: use Dagger2 + Gradle
问题描述
我理解Dagger2是如何工作的,
我明白它允许轻松地交换依赖关系,因此我们可以使用mock进行测试。
点是我不确定我是否理解如何为测试和调试/生产提供不同的Dagger2组件实现。
需要创建2个Gradle productFlavors(例如Production/Test)
,它将包含2个不同的Components定义吗?
我很困惑,请澄清一下会很好!
非常感谢!
单元测试
不要使用Dagger进行单元测试
为了用 @Inject
注释构造函数测试一个类,你不需要匕首。而是使用假或模拟依赖关系构造函数创建实例。
final类ThingDoer {
private final ThingGetter getter;
私人决赛ThingPutter推杆;
@Inject ThingDoer(ThingGetter getter,ThingPutter推杆){
this.getter = getter;
this.putter =推杆;
}
String doTheThing(int howManyTimes){/ * ... * /}
}
public class ThingDoerTest {
@Test
public void testDoTheThing(){
ThingDoer doer = new ThingDoer(fakeGetter,fakePutter);
assertEquals(done,doer.doTheThing(5));
功能/集成/最终测试
功能/集成/端到端测试通常使用生产
应用程序,假冒[fakes-not-mocks]持久性,
后端和授权系统,使应用程序的其余部分保持正常运行。这种方法有助于拥有一个测试配置(或者
小型有限数量)的测试配置,其中测试
配置将取代prod配置中的一些绑定。
您有两种选择:
选项1:通过子模块重写绑定
@Component(modules = {AuthModule.class,/ * ... * /})
接口MyApplicationComponent {/ * ... * /}
@Module
class AuthModule {
@Provides AuthManager authManager(AuthManagerImpl impl){
return impl;
类FakeAuthModule扩展AuthModule {
@Override
AuthManager authManager(AuthManagerImpl impl){
返回新的FakeAuthManager();
MyApplicationComponent testingComponent = DaggerMyApplicationComponent.builder()
.authModule(new FakeAuthModule())
.build();
选项2:分离组件配置
@Component(modules = {
OAuthModule.class,// real auth
FooServiceModule.class,//真实后端
OtherApplicationModule.class,
/ * ... * /})
接口ProductionComponent {
Server server();
}
@Component(modules = {
FakeAuthModule.class,// fake auth
FakeFooServiceModule.class,//假后端
OtherApplicationModule.class ,
/ * ... * /})
接口TestComponent继承ProductionComponent {
FakeAuthManager fakeAuthManager();
FakeFooService fakeFooService();
}
更多关于官方文档测试页面。
I understand how Dagger2 works,
I understand it allows to easily swap dependencies, so we can use mocks for testing.
Point is that I am not sure I understand how am I supposed to provide different Dagger2 Components implementations for testing and for debug/production.
Would I need to create 2 Gradle productFlavors (e.g "Production"/"Test")
that would contain 2 different Components definition?
Or can I specify that I want to use the mock Component for test compile and the non mock Component for non test builds?
I am confused, please some clarification would be great!
Thanks a lot!
解决方案 Unit testing
Don’t use Dagger for unit testing
For testing a class with @Inject
annotated constructor you don't need dagger. Instead create an instance using the constructor with fake or mock dependencies.
final class ThingDoer {
private final ThingGetter getter;
private final ThingPutter putter;
@Inject ThingDoer(ThingGetter getter, ThingPutter putter) {
this.getter = getter;
this.putter = putter;
}
String doTheThing(int howManyTimes) { /* … */ }
}
public class ThingDoerTest {
@Test
public void testDoTheThing() {
ThingDoer doer = new ThingDoer(fakeGetter, fakePutter);
assertEquals("done", doer.doTheThing(5));
}
}
Functional/integration/end-to-end testing
Functional/integration/end-to-end tests typically use the production
application, but substitute fakes[^fakes-not-mocks] for persistence,
backends, and auth systems, leaving the rest of the application to
operate normally. That approach lends itself to having one (or maybe a
small finite number) of test configurations, where the test
configuration replaces some of the bindings in the prod configuration.
You have two options here:
Option 1: Override bindings by subclassing modules
@Component(modules = {AuthModule.class, /* … */})
interface MyApplicationComponent { /* … */ }
@Module
class AuthModule {
@Provides AuthManager authManager(AuthManagerImpl impl) {
return impl;
}
}
class FakeAuthModule extends AuthModule {
@Override
AuthManager authManager(AuthManagerImpl impl) {
return new FakeAuthManager();
}
}
MyApplicationComponent testingComponent = DaggerMyApplicationComponent.builder()
.authModule(new FakeAuthModule())
.build();
Option 2: Separate component configurations
@Component(modules = {
OAuthModule.class, // real auth
FooServiceModule.class, // real backend
OtherApplicationModule.class,
/* … */ })
interface ProductionComponent {
Server server();
}
@Component(modules = {
FakeAuthModule.class, // fake auth
FakeFooServiceModule.class, // fake backend
OtherApplicationModule.class,
/* … */})
interface TestComponent extends ProductionComponent {
FakeAuthManager fakeAuthManager();
FakeFooService fakeFooService();
}
More about it in the official documentation testing page.
这篇关于Android测试:使用Dagger2 + Gradle的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!