android - 在 Activity 中注入(inject) ViewModelFactory.Provider 以进行浓缩咖啡测试

标签 android dagger-2

与此问题相关:Espresso, Dagger2 set ViemodelProvider.Factory on BaseActivity

在我的测试期间,为了让 espresso 测试在 Android 架构组件上工作,我经历了 hell 并返回到 Activity 上的 ViewModelFactory.Provider。我原以为它很简单,但我想它不是......

使用 fragment 的示例很简单:
https://github.com/googlesamples/android-architecture-components/blob/master/GithubBrowserSample/app/src/androidTest/java/com/android/example/github/ui/user/UserFragmentTest.java

@Before
public void init() {
    UserFragment fragment = UserFragment.create("foo");
    viewModel = mock(UserViewModel.class);
    when(viewModel.getUser()).thenReturn(userData);
    when(viewModel.getRepositories()).thenReturn(repoListData);
    navigationController = mock(NavigationController.class);
    fragmentBindingAdapters = mock(FragmentBindingAdapters.class);

    fragment.viewModelFactory = ViewModelUtil.createFor(viewModel);
    fragment.navigationController = navigationController;
    fragment.dataBindingComponent = () -> fragmentBindingAdapters;

    activityRule.getActivity().setFragment(fragment);
}

但是,这根本不适用于 Activity ,因为我无法在 Activity 创建之前使用 ActivityTestRule 获取 Activity 的依赖项。
我使用 Dagger2 遵循与上面示例中相同的新依赖项注入(inject)流程,使用 HasActivityInjector 接口(interface)。

非常感谢您的帮助!

最佳答案

可以通过在 @Before 方法中的 TestApp 中注册自定义 ActivityLifecycleCallbacks 来设置注入(inject)的 Activity 属性。

例子:

 @Before
public void init(){


    UserFragment fragment = UserFragment.create("foo");
    viewModel = mock(UserViewModel.class);
    when(viewModel.getUser()).thenReturn(userData);
    when(viewModel.getRepositories()).thenReturn(repoListData);
    navigationController = mock(NavigationController.class);


    TestApp testApp = ((TestApp) InstrumentationRegistry.getContext().getApplicationContext());
    testApp.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
        @Override
        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
            //will be called before the onCreate method of your activity
            activity.setViewModelFactory(ViewModelUtil.createFor(viewModel));
        }

        @Override
        public void onActivityStarted(Activity activity) {

        }

        @Override
        public void onActivityResumed(Activity activity) {

        }

        @Override
        public void onActivityPaused(Activity activity) {

        }

        @Override
        public void onActivityStopped(Activity activity) {

        }

        @Override
        public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

        }

        @Override
        public void onActivityDestroyed(Activity activity) {

        }
    });


    fragment.viewModelFactory = ViewModelUtil.createFor(viewModel);
    fragment.navigationController = navigationController;
    fragment.dataBindingComponent = () -> fragmentBindingAdapters;

    activityRule.getActivity().setFragment(fragment);


}

关于android - 在 Activity 中注入(inject) ViewModelFactory.Provider 以进行浓缩咖啡测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46533989/

相关文章:

kotlin - Kotlin 中的 Dagger 2 : Is there a way to do injection for class with default parameterized constructor without using Module?

android - Kotlin Dagger2 找不到符号 ApplicationModule_ProvideApplicationFactory

java - 我似乎无法弄清楚如何修复我的 ksoap2 android 代码中的错误

android - Android中随机改变背景图片

android - 无法在 Play 上安装我的第一个应用。支持设备之间的 Galaxy Nexus,但显然不是我的 Nexus

android - Dagger 2 无法识别 Kotlin 中的提供方法。 Java 工作正常

java - 如何使用 Rxjava2 在 Room 数据库中的 Textview 上显示 Flowable 数据

java - 如何使用 SQL 数据库在 Fragment 上创建 Adapter ListView?

java - 使用 dagger2 将类注入(inject)到 workmanager (java)

android - ViewModelFactory can't create an instance 错误创建自定义ViewModelFactory类