简体   繁体   English

有没有一种简单的方法可以在使用FragmentScenario的测试中注入匕首模拟?

[英]Is there a simple way to inject dagger mocks in tests using FragmentScenario?

I've just come across FragmentScenario and would like to use it to test Fragments in isolation. 我刚刚遇到了FragmentScenario,并想用它来隔离地测试Fragments。 But my app uses Dagger and I can't find a good way to run the FragmentScenario and get mocked fields into the fragment under test. 但是我的应用程序使用Dagger,我找不到一种运行FragmentScenario并将模拟字段放入待测片段的好方法。 My current test setup launches an Activity and uses DaggerMock to inject mockito mock dependencies. 我当前的测试设置将启动一个Activity,并使用DaggerMock来注入Mockito模拟依赖项。 However I would really like to add isolated fragment tests. 但是我真的很想添加隔离的片段测试。

Is it possible to do this with FragmentScenario? 可以使用FragmentScenario做到这一点吗? Will it be supported sometime soon? 会很快得到支持吗?

I've seen this article suggesting a solution but I don't like the idea of having to open fragment classes just for testing https://proandroiddev.com/testing-dagger-fragments-with-fragmentscenario-155b6ad18747 我已经看到这篇文章提出了一种解决方案,但我不喜欢只为测试https://proandroiddev.com/testing-dagger-fragments-with-fragmentscenario-155b6ad18747而打开片段类的想法

I used a solution for a similar scenario at activity level, please see How do you re-inject an android object, (Service, Activity...) being injected into by an AndroidInjector, into other objects? 我在活动级别针对类似情况使用了解决方案,请参阅如何将由AndroidInjector注入的android对象(服务,活动...)重新注入其他对象? for reference. 以供参考。

How can we apply this solution 我们如何应用此解决方案

consider: 考虑:

class MyFragment extends Fragment
{
 ....
}

make a subclass: 做一个子类:

class MyFragmentInjector extends MyFragment
{
   public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup 
      container,  @Nullable Bundle savedInstanceState) {
      initialiseDependencies();
      super.onCreateView(inflater, container, savedInstanceState);
   }

   public void initialiseDependencies()
   {
      DaggerMyFragmentComponent.Factory.create().inject(this);
   }
}

Make a test implementation subclass 使测试实现子类

class MyFragmentInjectorTestImpl extends MyFragment
{
   public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup 
      container,  @Nullable Bundle savedInstanceState) {
      initialiseDependencies();
      super.onCreateView(inflater, container, savedInstanceState);
   }

   public void initialiseDependencies()
   {
      DaggerMyFragmentTestComponent.Factory.create().inject(this);
   }
}

Your test component would contain all of your mocked modules to replace your real ones: 您的测试组件将包含所有模拟模块以替换实际模块:

This means that to run your test you would have: 这意味着要运行测试,您将具有:

FragmentScenario.launch(MyFragmentInjectorTestImpl.class);

and use 和使用

 FragmentScenario.FragmentAction<MyFragmentInjectorTestImpl> mAction;

but since MyFragmentInjectorTestImpl is still and instance of MyFragment you will be testing MyFragment with your mock dependencies injected. 但是由于MyFragmentInjectorTestImpl仍然是MyFragment的实例,因此您将使用注入的模拟依赖项测试MyFragment。

The problem is that all of this initialisation has to be done at a subclass level (because it needs to inject the dependencies into its parent), which is not ideal, if you have many fragments it seems like there are a lot of unnecessary extra class implementations but it means that your MyFragment class with your real code is somewhat cleaner. 问题是所有这些初始化都必须在子类级别完成(因为它需要将依赖项注入到其父级中),这不是理想的选择,如果您有很多片段,似乎有很多不必要的额外类实现,但这意味着带有实际代码的MyFragment类更加干净。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM