不模拟单元测试中的Android ArraySet

问题描述 投票:0回答:1

在代码中使用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

android unit-testing mockito powermock powermockito
1个回答
0
投票

您不应在非Android测试类中使用android sdk类。但是,如果您愿意,可以使用类似以下内容:

    @Test
public void testArraySet() {
    final Set<Bird> fakeBirds = new HashSet<>();
    ArraySet<Bird> birds = (ArraySet<Bird>) Mockito.mock(ArraySet.class);

    when(birds.add(any(Bird.class))).then(new Answer<Boolean>() {
        @Override
        public Boolean answer(InvocationOnMock invocation) throws Throwable {
            Bird param = invocation.getArgument(0);
            return fakeBirds.add(param);
        }
    });

    when(birds.contains(any(Bird.class))).then(new Answer<Boolean>() {
        @Override
        public Boolean answer(InvocationOnMock invocation) throws Throwable {
            Bird param = invocation.getArgument(0);
            return fakeBirds.contains(param);
        }
    });

    Bird bird = new Bird();
    birds.add(bird);

    assert birds.contains(bird);
}
© www.soinside.com 2019 - 2024. All rights reserved.