根据Dagger 2文档
我正在尝试根据Dagger2's documentation
设置测试环境(仅针对上下文,我已在Dagger 1中成功完成此操作。)
问题,特别是,虽然Dagger2正确生成DaggerRoboDaggerComponent(在App.java中使用),但它不会生成DaggerTestRoboDaggerComponent(在MainActivityTest.java中使用)。我检查了目录结构,以确保它没有隐藏在一些不起眼的地方,并完成必要的清理,重建,无效缓存/重启等等。
如果有人可以请让我知道我的方式的错误,我会很感激。提前谢谢。
或者,浏览下面的项目文件:
的build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "xx.robodagger"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
compile 'com.google.dagger:dagger:2.10'
annotationProcessor "com.google.dagger:dagger-compiler:2.10"
testCompile 'junit:junit:4.12'
testCompile "org.robolectric:robolectric:3.3.1"
}
App.java
package xx.robodagger;
import android.app.Application;
public class App extends Application {
static RoboDaggerComponent roboDaggerComponent;
static RoboDaggerComponent getComponent() {
return roboDaggerComponent;
}
@Override public void onCreate() {
super.onCreate();
roboDaggerComponent = DaggerRoboDaggerComponent.builder()
.roboDaggerModule(new RoboDaggerModule())
.build();
}
}
Foo.java
package xx.robodagger;
class Foo {
@Override public String toString() {
return "foo";
}
}
MainActivity.java
package xx.robodagger;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import javax.inject.Inject;
public class MainActivity extends AppCompatActivity {
@Inject Foo foo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
App.getComponent().inject(this);
setContentView(R.layout.activity_main);
TextView tv = (TextView)findViewById(R.id.textview);
tv.setText(foo.toString());
}
}
RoboDaggerComponent.java
package xx.robodagger;
import javax.inject.Singleton;
import dagger.Component;
@Singleton
@Component(modules={RoboDaggerModule.class})
interface RoboDaggerComponent {
void inject(MainActivity mainActivity);
}
RoboDaggerModule.java
package xx.robodagger;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
@SuppressWarnings("unused")
@Module
class RoboDaggerModule {
@Provides
@Singleton
Foo providesFoo() { return new Foo(); }
}
现在在测试目录中,
FakeFoo.java
package xx.robodagger;
class FakeFoo extends Foo {
@Override public String toString() {
return "bar";
}
}
MainActivityTest.java
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import javax.inject.Inject;
@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class)
public class MainActivityTest {
TestRoboDaggerComponent testRoboDaggerComponent;
@Inject Foo foo;
@Before
public void setup() {
testRoboDaggerComponent = DaggerTestRoboDaggerComponent.builder()
.testRoboDaggerModule(new TestRoboDaggerModule())
.build();
testRoboDaggerComponent.inject(this);
}
@Test
public void fooBarTest() {
assert(foo.toString().equals("bar"));
}
}
TestRoboDaggerComponent.java
package xx.robodagger;
import javax.inject.Singleton;
import dagger.Component;
@Singleton
@Component(modules={TestRoboDaggerModule.class})
interface TestRoboDaggerComponent {
void inject(MainActivityTest mainActivityTest);
}
TestRoboDaggerModule.java
package xx.robodagger;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
@SuppressWarnings("unused")
@Module
class TestRoboDaggerModule {
@Provides
@Singleton
Foo providesFoo() { return new FakeFoo(); }
}
答案 0 :(得分:1)
删除TestRoboDaggerComponent.java
,不需要
修改App.java
以通过受保护的方法设置组件
@Override public void onCreate() {
super.onCreate();
setupComponent();
}
protected void setupComponent() {
roboDaggerComponent = DaggerRoboDaggerComponent.builder()
.roboDaggerModule(new RoboDaggerModule())
.build();
}
修改TestApp.java
以扩展App
,并使用TestModule覆盖前面提到的方法
public class TestApp extends App {
@Override
protected void setupComponent() {
roboDaggerComponent = DaggerRoboDaggerComponent.builder()
.roboDaggerModule(new TestRoboDaggerModule())
.build();
}
}
最后,在实际测试中,利用Robolectric的功能指定应用程序模块
@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class,
application = TestApp.class)
public class MainActivityTest {
private MainActivity mainActivity;
@Before
public void setup() {
mainActivity = Robolectric.setupActivity(MainActivity.class);
}
@Test
public void fooBarTest() {
TextView tv = (TextView)mainActivity.findViewById(R.id.textview);
assert(tv.getText().equals("bar"));
}
}
请注意,实际测试中没有任何DI。 MainActivity的注入按预期方式进行,并使用覆盖的模块。如果您有一个在构造函数中使用@Injects的依赖项,则Dagger文档的解决方案是 not 而不是在测试中使用注入,而只是使用模拟对象调用普通的构造函数。这一切都说得通。我仍然认为最初报告的问题是一个错误,但无论如何。