在测试应用程序中使用 Dagger 和 Robolectric
Using Dagger and Robolectric with test application
我将 MVP 模式与片段 (GalleryFragment
) 一起使用,其中应用程序 class(MainApplication
) 来源 MainActivityRepository
和 GalleryFragmentPresenter
(分组为DIModules
) 通过字段注入提供给 Fragment。
要单独测试 GalleryFragment
,我的想法是使用 Robolectric 配置 (@Config) 完全用自定义 TestApplication
源 [=25] 替换 MainApplication
=].
GalleryFragmentTest
运行s 直到 startFragment(galleryFragment)
但我在 GalleryFragment
.
内的 MainApplication.getComponent().inject(this);
处得到 NullPointerException
我怀疑这是因为这一行专门使用 MainApplication
而其他所有内容都由 Robolectric @Config 设置的 TestApplication
处理,但我不确定,我正在寻找有关如何使用此自定义 TestApplication
.
成功 运行 测试的建议
在寻找可能的解决方案时,我发现了有关使用 Dagger 支持库中的 AndroidInjector 的信息,这将完全摆脱 MainApplication.getComponent().inject(this);
但这行得通吗?
https://android.jlelse.eu/android-and-dagger-2-10-androidinjector-5e9c523679a3
GalleryFragment.java
public class GalleryFragment extends Fragment {
@Inject
public MainActivityRepository mRepository;
@Inject
public GalleryFragmentPresenter mGalleryFragmentPresenter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainApplication.getComponent().inject(this); //NullPointerException here
mGalleryFragmentPresenter.initialize(mRepository, value);
}
}
DIModules.java
@Module
public class DIModules {
@Provides
public GalleryFragmentPresenter provideGalleryFragmentPresenter(){
return new GalleryFragmentPresenter();
}
@Provides
@Singleton
public MainActivityRepository provideMainActivityRepository(){
return new MainActivityRepository();
}
}
AppComponent.java
@Singleton
@Component(modules = DIModules.class)
public interface AppComponent {
void inject(GalleryFragment galleryFragment);
}
MainApplication.java
public class MainApplication extends Application {
public static AppComponent component;
@Override
public void onCreate() {
super.onCreate();
Realm.init(this);
component = buildComponent();
}
public static AppComponent getComponent() {
return component;
}
protected AppComponent buildComponent(){
return DaggerAppComponent
.builder()
.dIModules(new DIModules())
.build();
}
}
TestApplication.java
public class TestApplication extends Application {
public static AppComponent component;
@Override
public void onCreate() {
super.onCreate();
component = buildComponent();
}
public static AppComponent getComponent() {
return component;
}
protected AppComponent buildComponent(){
return DaggerAppComponent.builder()
.dIModules(new mockDIModules())
.build();
}
}
GalleryFragmentTest.java
@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class,
application = TestApplication.class)
public class GalleryFragmentTest {
@Test
public void allItemTabTest() throws Exception {
GalleryFragment galleryFragment = GalleryFragment.newInstance(value);
startFragment(galleryFragment);
assertNotNull(galleryFragment);
}
}
我正在使用 dagger
、dagger-android-support
、dagger-compiler
版本 2.14.1 和 robolectric:3.6.1
当然是null
。当您在测试应用程序中执行操作时,您的片段仍会尝试使用生产应用程序。
将您的注入代码更改为下一个:
((MainApplication) getContext().getApplicationContext()).getComponent().inject(this);
并且还要使您的应用程序 getComponent()
中的方法不是静态的,因此测试应用程序会覆盖它。
另一种选择是将您的 TestApplication
更改为下一个:
public class TestApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
buildComponent();
}
private void buildComponent(){
Application.component = DaggerAppComponent.builder()
.dIModules(new mockDIModules())
.build();
}
}
我将 MVP 模式与片段 (GalleryFragment
) 一起使用,其中应用程序 class(MainApplication
) 来源 MainActivityRepository
和 GalleryFragmentPresenter
(分组为DIModules
) 通过字段注入提供给 Fragment。
要单独测试 GalleryFragment
,我的想法是使用 Robolectric 配置 (@Config) 完全用自定义 TestApplication
源 [=25] 替换 MainApplication
=].
GalleryFragmentTest
运行s 直到 startFragment(galleryFragment)
但我在 GalleryFragment
.
MainApplication.getComponent().inject(this);
处得到 NullPointerException
我怀疑这是因为这一行专门使用 MainApplication
而其他所有内容都由 Robolectric @Config 设置的 TestApplication
处理,但我不确定,我正在寻找有关如何使用此自定义 TestApplication
.
在寻找可能的解决方案时,我发现了有关使用 Dagger 支持库中的 AndroidInjector 的信息,这将完全摆脱 MainApplication.getComponent().inject(this);
但这行得通吗?
https://android.jlelse.eu/android-and-dagger-2-10-androidinjector-5e9c523679a3
GalleryFragment.java
public class GalleryFragment extends Fragment {
@Inject
public MainActivityRepository mRepository;
@Inject
public GalleryFragmentPresenter mGalleryFragmentPresenter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainApplication.getComponent().inject(this); //NullPointerException here
mGalleryFragmentPresenter.initialize(mRepository, value);
}
}
DIModules.java
@Module
public class DIModules {
@Provides
public GalleryFragmentPresenter provideGalleryFragmentPresenter(){
return new GalleryFragmentPresenter();
}
@Provides
@Singleton
public MainActivityRepository provideMainActivityRepository(){
return new MainActivityRepository();
}
}
AppComponent.java
@Singleton
@Component(modules = DIModules.class)
public interface AppComponent {
void inject(GalleryFragment galleryFragment);
}
MainApplication.java
public class MainApplication extends Application {
public static AppComponent component;
@Override
public void onCreate() {
super.onCreate();
Realm.init(this);
component = buildComponent();
}
public static AppComponent getComponent() {
return component;
}
protected AppComponent buildComponent(){
return DaggerAppComponent
.builder()
.dIModules(new DIModules())
.build();
}
}
TestApplication.java
public class TestApplication extends Application {
public static AppComponent component;
@Override
public void onCreate() {
super.onCreate();
component = buildComponent();
}
public static AppComponent getComponent() {
return component;
}
protected AppComponent buildComponent(){
return DaggerAppComponent.builder()
.dIModules(new mockDIModules())
.build();
}
}
GalleryFragmentTest.java
@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class,
application = TestApplication.class)
public class GalleryFragmentTest {
@Test
public void allItemTabTest() throws Exception {
GalleryFragment galleryFragment = GalleryFragment.newInstance(value);
startFragment(galleryFragment);
assertNotNull(galleryFragment);
}
}
我正在使用 dagger
、dagger-android-support
、dagger-compiler
版本 2.14.1 和 robolectric:3.6.1
当然是null
。当您在测试应用程序中执行操作时,您的片段仍会尝试使用生产应用程序。
将您的注入代码更改为下一个:
((MainApplication) getContext().getApplicationContext()).getComponent().inject(this);
并且还要使您的应用程序 getComponent()
中的方法不是静态的,因此测试应用程序会覆盖它。
另一种选择是将您的 TestApplication
更改为下一个:
public class TestApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
buildComponent();
}
private void buildComponent(){
Application.component = DaggerAppComponent.builder()
.dIModules(new mockDIModules())
.build();
}
}