首页 > 解决方案 > 单元测试中的 Android ArraySet 未被模拟

问题描述

在代码中使用android.util.ArraySet时,我无法在非 android 测试类中测试使用它的类,因为它会引发异常:

java.lang.RuntimeException:在 android.util.ArraySet 中添加的方法未模拟。有关详细信息,请参阅http://g.co/androidstudio/not-mocked

链接说:

这是为了确保您的单元测试只测试您的代码,而不依赖于 Android 平台的任何特定行为(您没有明确地模拟,例如使用 Mockito)

如何使用 ArraySet 对代码进行单元测试?我会说以某种方式“用 HashSet 替换它”来模拟(Mockito,PowerMock)它可能是有希望的:

要测试的代码:

Set<Bird> birds = new ArraySet<>();
birds.add(currentBird);

测试代码:

whenNew(ArraySet.class).withAnyArguments().thenAnswer(new Answer<Object>() {
    @Override
    public Object answer(InvocationOnMock invocation) throws Throwable {
        return new HashSet();
    }
});

这给了java.lang.ClassCastException: java.util.HashSet cannot be cast to android.util.ArraySet.

一种解决方法是不返回 aHashSet但一些MyFakeArraySet extends ArraySet(内部使用 a HashSet),但遗憾ArraySet的是final. :-(

标签: androidunit-testingmockitopowermockpowermockito

解决方案


我发现测试文件夹中的类似乎具有优先权。所以我不必嘲笑任何东西。我可以将一个包android.util放入我的测试文件夹和一个ArraySet完全由我指定的类:

package android.util;

import android.support.annotation.NonNull;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;


public class ArraySet<E extends Object> implements Collection<E>, Set<E> {
    private final HashSet<E> HASH_SET;

    public ArraySet(int capacity) {
        Log.e("ArraySet", "WARNING, using fake array set!");
        HASH_SET = new HashSet<>(capacity);
    }

    @Override
    public int size() {
        return HASH_SET.size();
    }

    // Do this with all other methods as well: Chain them into HASH_SET.
}

推荐阅读