在安卓中为使用Espresso进行片段隔离测试创建ViewModel的示例。

huangapple 未分类评论58阅读模式
英文:

Creating ViewModel doubles in android for testing fragments in isolation with espresso

问题

我在使用Java开发Android应用。

我们的目标是在隔离环境中测试我们应用的一个片段(Fragment)。

我们的问题是,我们需要设置一个视图模型(view-model)的双重实例,以便创建有意义且值得测试的片段状态。

特别地,模拟我们的片段的模型视图(model-view)依赖于另一个视图模型。

在我们的研究中,我们了解到视图模型存储在特定的视图模型存储对象中,是否有一种通过Espresso在常规方式而非繁琐方式来操纵此存储位置的方法?也许可以通过与FragmentScenario对象的一些交互来实现?

下图说明了我们的情况。

在安卓中为使用Espresso进行片段隔离测试创建ViewModel的示例。

为了阐明我注入视图模型的方式,我附上了我的片段代码:

  1. public class CornerDetectionFragment extends Fragment {
  2. private CornerDetectionViewModel cornerDetectionViewModel;
  3. @Nullable
  4. @Override
  5. public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
  6. cornerDetectionViewModel =
  7. ViewModelProviders.of(
  8. this,
  9. new CornerDetectionViewModelFactory(getActivity())
  10. ).get(CornerDetectionViewModel.class);
  11. View root = inflater.inflate(R.layout.fragment_corner_detection, container, false);
  12. ((TextView) root.findViewById(R.id.textView_relative_cirrent_location)).setText(
  13. "1/" + cornerDetectionViewModel.getNumberOfCornerDetectedCaptures().getValue()
  14. );
  15. return root;
  16. }
  17. /*...*/
  18. }

还有视图模型工厂的代码:

  1. public class CornerDetectionViewModelFactory implements ViewModelProvider.Factory {
  2. FragmentActivity activity;
  3. public CornerDetectionViewModelFactory(FragmentActivity activity) {
  4. this.activity = activity;
  5. }
  6. @NonNull
  7. @Override
  8. public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
  9. return (T) ViewModelProviders.of(
  10. activity,
  11. new InitialFactory())
  12. .get(CornerDetectionViewModel.class
  13. );
  14. }
  15. private class InitialFactory implements ViewModelProvider.Factory{
  16. @NonNull
  17. @Override
  18. public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
  19. return (T) new CornerDetectionViewModel(
  20. new ImageProcessingFactory().create(),
  21. new ResolveAnswersViewModelFactory(activity)
  22. .create(ResolveAnswersViewModel.class)
  23. );
  24. }
  25. }
  26. }

谢谢。

英文:

I'm working with android in Java.

Our goal is to test a fragment of our app in isolation.

Our problem is that we need to setup a view-model double to in order to create meaningful and test worthy fragment state.

In particular, the model-view that models our fragment depends on another view model.

In our research, we learned that view-models are stored in some specific view-model-store object, is there a way to manipulate this storage location from espresso in a conventional not to hacky way? via maybe some interaction with a FragmentScenrario object?

The figure ilustrates our situation.

在安卓中为使用Espresso进行片段隔离测试创建ViewModel的示例。

I'm appending my fragment code to clarify the way I'm injecting the view-model:

  1. public class CornerDetectionFragment extends Fragment {
  2. private CornerDetectionViewModel cornerDetectionViewModel;
  3. @Nullable
  4. @Override
  5. public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
  6. cornerDetectionViewModel =
  7. ViewModelProviders.of(
  8. this,
  9. new CornerDetectionViewModelFactory(getActivity())
  10. ).get(CornerDetectionViewModel.class);
  11. View root =inflater.inflate(R.layout.fragment_corner_detection, container, false);
  12. ((TextView)root.findViewById(R.id.textView_relative_cirrent_location)).setText(
  13. &quot;1/&quot;+cornerDetectionViewModel.getNumberOfCornerDetectedCaptures().getValue()
  14. );
  15. return inflater.inflate(R.layout.fragment_corner_detection, container, false);
  16. }
  17. /*...*/
  18. }

And also the code of the view-model factory:

  1. public class CornerDetectionViewModelFactory implements ViewModelProvider.Factory {
  2. FragmentActivity activity;
  3. public CornerDetectionViewModelFactory(FragmentActivity activity) {
  4. this.activity = activity;
  5. }
  6. @NonNull
  7. @Override
  8. public &lt;T extends ViewModel&gt; T create(@NonNull Class&lt;T&gt; modelClass) {
  9. return (T) ViewModelProviders.of(
  10. activity,
  11. new InitialFactory())
  12. .get(CornerDetectionViewModel.class
  13. );
  14. }
  15. private class InitialFactory implements ViewModelProvider.Factory{
  16. @NonNull
  17. @Override
  18. public &lt;T extends ViewModel&gt; T create(@NonNull Class&lt;T&gt; modelClass) {
  19. return (T)new CornerDetectionViewModel(
  20. new ImageProcessingFactory().create(),
  21. new ResolveAnswersViewModelFactory(activity)
  22. .create(ResolveAnswersViewModel.class)
  23. );
  24. }
  25. }
  26. }

Thanks.

huangapple
  • 本文由 发表于 2020年3月16日 06:36:26
  • 转载请务必保留本文链接:https://java.coder-hub.com/60698368.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定