Android 使用Dagger和Robolectric及其测试应用

Android 使用Dagger和Robolectric及其测试应用,android,dependency-injection,dagger-2,robolectric,android-mvp,Android,Dependency Injection,Dagger 2,Robolectric,Android Mvp,我将MVP模式与片段(GalleryFragment)一起使用,其中应用程序类(MainApplication)源MainActivityRepository和GalleryFragmentPresenter(分组为DIModules)通过字段注入提供给片段 为了单独测试GalleryFragment,我的想法是使用Robolectric配置(@Config)将main应用程序完全替换为定制的TestApplicationsourcingMockDiModule GalleryFragmentT

我将MVP模式与片段(
GalleryFragment
)一起使用,其中应用程序类(
MainApplication
)源
MainActivityRepository
GalleryFragmentPresenter
(分组为
DIModules
)通过字段注入提供给片段

为了单独测试
GalleryFragment
,我的想法是使用Robolectric配置(@Config)将
main应用程序
完全替换为定制的
TestApplication
sourcing
MockDiModule

GalleryFragmentTest
一直运行到
startFragment(galleryFragment)
但是我在
main应用程序.getComponent().inject(这个)中得到一个NullPointerException内部
GalleryFragment

我怀疑这是因为这一行专门使用了
main应用程序
,而其他一切都是由roblectric@Config设置的
TestApplication
处理的,但我不确定,我正在寻找关于如何使用此自定义
TestApplication
成功运行测试的建议

在寻找可能的解决方案时,我从Dagger支持库中发现了使用Androidjector的方法,它将摆脱
MainApplication.getComponent().inject(这个)完全正确,但这行吗?

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);
    }
}
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();
    }
}
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();
    }
}
TestApplication.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();
    }
}
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支持
dagger编译器
2.14.1版和
robolectric:3.6.1
当然,它是
null
。当您在测试应用程序中执行操作时,您的片段仍然尝试使用生产应用程序

将注入代码更改为下一个:

((MainApplication) getContext().getApplicationContext()).getComponent().inject(this);
并将应用程序中的方法
getComponent()
设置为非静态,以便测试应用程序覆盖它

另一个选项是将
测试应用程序更改为下一个:

public class TestApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        buildComponent();
    }

    private void buildComponent(){
        Application.component = DaggerAppComponent.builder()
                .dIModules(new mockDIModules())
                .build();
    }
}

在进行更改后,我得到了ClassCastException,但扩展了
MainApplication
修复了它。谢谢你的帮助:)