繁体   English   中英

Mockito 用处理器测试 class

[英]Mockito tests for class with Handler

我是 android dev 中的新人,所以我有一个包含 viewPager 的应用程序,其中包含 2 个 UI 片段和 1 个执行操作的非 UIFragment(我使用了“setRetainInstance(true)”,它已弃用,但我必须使用它)。 在这个 nonUIFragment 中,我有 Handler,它接受来自 ExecutorServices 开始的操作的消息。 但现在我的任务是用 Mockito 测试这个应用程序,我完全糊涂了。

Mentor 说“您必须模拟产生结果的操作,在非 UIFragment 中执行,并将其结果存储在集合中。”

必须如何看待这个测试,我无法创建spy() class NonUIFragment 并使用真实方法,因为“android.os.Looper 中的方法 getMainLooper 未模拟。” 我所有的方法都是无效的,他们不返回任何东西,我怎么能追踪这个链。

NonUIFragment.java

private NonUIToActivityInterface nonUIInterface;
    private final Map<DefOperandTags, HashMap<DefOperationTags, String>> allResultsMap
        = new HashMap<>();

 @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
    }

//Handler pass result to here
    public void passAndSaveResult(DefOperandTags operandTag, DefOperationTags operationTag, String result) {
        allResultsMap.get(operandTag)).put(operationTag, result);
    }

private final Handler handler = new Handler(Looper.getMainLooper()) {
        public void handleMessage(Message msg) {
            if (msg.what != null)
                passAndSaveResult(defOperandTags, defOperationTag, msg.obj.toString());
    };

OneOfOperation.java(将值添加到列表中)

public class AddToStartList extends Operation {

    public AddToStartList(List list, DefOperationTags operationTag) {
        super(list);
        key = operationTag;
    }

    @Override
    public void operation(Object collection) {
        ((List)collection).add(0, "123");
    }

那么,我该如何执行我的导师所说的呢?

这会很棘手,因为您的 Android 测试库没有实现,而且 static 方法通常更难以安全有效地模拟。

最新版本的 Mockito 增加了模拟 static 方法的能力,而无需使用像PowerMock这样的另一个库,所以第一选择就是这样。 如果可能的话,在Looper::getMainLooper上使用mockStatic来模拟。

另一种解决方案是添加一些间接性,为您提供测试接缝:

public class NonUIFragment extends Fragment {
  /** Visible for testing. */
  static Looper overrideLooper;

  // ...

  private final Handler handler = new Handler(
      overrideLooper != null ? overrideLooper : Looper.getMainLooper()) {
    /* ... */
  };
}

最后,如果你发现自己经常做这种模拟,你可以考虑像Robolectric这样的库。 使用 Robolectric,您可以使用ShadowLooper 模拟Looper,这可以让您远程控制它,同时将 Mockito 用于您的团队编写的任何类。 例如,这将防止您不得不为每个测试模拟一个真实的 Looper。

暂无
暂无

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

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