在测试应用程序中使用 Dagger 和 Robolectric

Using Dagger and Robolectric with test application

我将 MVP 模式与片段 (GalleryFragment) 一起使用,其中应用程序 class(MainApplication) 来源 MainActivityRepositoryGalleryFragmentPresenter(分组为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);
    }
}

我正在使用 daggerdagger-android-supportdagger-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();
    }
}