[英]Using Dagger and Robolectric with test application
I am using MVP pattern with a Fragment( GalleryFragment
), where Application class( MainApplication
) sources MainActivityRepository
and GalleryFragmentPresenter
(grouped as DIModules
) which are provided to Fragment through field injection. 我正在使用带有Fragment(
GalleryFragment
)的MVP模式,其中Application类( MainApplication
)通过字段注入提供给Fragment的MainActivityRepository
和GalleryFragmentPresenter
(分组为DIModules
)。
To test GalleryFragment
in isolation, my idea was to use Robolectric configuration(@Config) to replace MainApplication
entirely with a custom TestApplication
sourcing mockDIModules
. 为了测试
GalleryFragment
孤立,我的想法是使用Robolectric配置(@Config)取代MainApplication
与定制完全TestApplication
采购mockDIModules
。
GalleryFragmentTest
runs until startFragment(galleryFragment)
but I get a NullPointerException at MainApplication.getComponent().inject(this);
GalleryFragmentTest
一直运行到startFragment(galleryFragment)
但我在MainApplication.getComponent().inject(this);
得到一个NullPointerException MainApplication.getComponent().inject(this);
inside GalleryFragment
. 在
GalleryFragment
。
I suspect this is because this line specifically uses MainApplication
while everything else is dealt with TestApplication
set by Robolectric @Config, but I'm not sure and I am looking for advice on how to successfully run tests using this custom TestApplication
. 我怀疑这是因为这一行专门使用
MainApplication
而其他所有内容都由Robolectric TestApplication
设置的TestApplication处理,但我不确定,我正在寻找有关如何使用此自定义TestApplication
成功运行测试的TestApplication
。
While searching for possible solutions, I found out about using AndroidInjector from Dagger support library, which will get rid of MainApplication.getComponent().inject(this);
在搜索可能的解决方案时,我发现了使用Dagger支持库中的
MainApplication.getComponent().inject(this);
,它将摆脱MainApplication.getComponent().inject(this);
entirely but would this work? 完全但这会有用吗? https://android.jlelse.eu/android-and-dagger-2-10-androidinjector-5e9c523679a3
https://android.jlelse.eu/android-and-dagger-2-10-androidinjector-5e9c523679a3
GalleryFragment.java 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 DIModules.java
@Module
public class DIModules {
@Provides
public GalleryFragmentPresenter provideGalleryFragmentPresenter(){
return new GalleryFragmentPresenter();
}
@Provides
@Singleton
public MainActivityRepository provideMainActivityRepository(){
return new MainActivityRepository();
}
}
AppComponent.java AppComponent.java
@Singleton
@Component(modules = DIModules.class)
public interface AppComponent {
void inject(GalleryFragment galleryFragment);
}
MainApplication.java 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 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 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);
}
}
I am using dagger
, dagger-android-support
, dagger-compiler
version 2.14.1 and robolectric:3.6.1
我使用的是
dagger
, dagger-android-support
, dagger-compiler
版本2.14.1和robolectric:3.6.1
Of course, it is null
. 当然,它是
null
。 Your fragment still tries to work with production application while you're doing things in the test application. 当您在测试应用程序中执行操作时,您的片段仍会尝试使用生产应用程序。
Change your injection code to next: 将注射代码更改为下一个:
((MainApplication) getContext().getApplicationContext()).getComponent().inject(this);
And also make the method in your Application getComponent()
as not static, so test app overrides it. 并且还将您的Application
getComponent()
方法设置为非静态,因此测试应用程序会覆盖它。
Another option is to change your TestApplication
to next: 另一种选择是将
TestApplication
更改为下一个:
public class TestApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
buildComponent();
}
private void buildComponent(){
Application.component = DaggerAppComponent.builder()
.dIModules(new mockDIModules())
.build();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.