java - 多次调用时用于 Iterable 实现的模拟拆分器?

标签 java unit-testing mockito java-stream

我在模拟 Iterable 类并调用 spliterator() 时遇到问题。一次调用 spliterator 时一切正常,但第二次调用没有返回任何值。

由于模拟总是返回相同的 Spliterator 实例,我假设状态没有被重置。有办法做到这一点吗?

这是我能给出的最小的例子

调用mapStringToHash是现实生活中的一个Lib,无法更改。 MyIterable 也不在我的控制之下。

package net.test;

import static org.hamcrest.CoreMatchers.is;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static java.util.stream.Collectors.toList;
import static org.hamcrest.MatcherAssert.assertThat;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Spliterator;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class SpliteratorTest {

    class MyIterable<T> implements Iterable<T> {

        private List<T> list;

        MyIterable(List<T> list) {
            this.list = new ArrayList<>(list);
        }

        @Override
        public Iterator<T> iterator() {
            return list.iterator();
        }

        @Override
        public Spliterator<T> spliterator() {
            return list.spliterator();
        }
    }

    // this a library method
    private Stream<Integer> mapStringToHash(final MyIterable<String> myIterable) {
        return StreamSupport.stream(myIterable.spliterator(), false).map(String::hashCode);
    }

    @Test
    public void testSeveralSpliteratorCalls() {
        MyIterable myIterable = givenMyIterableMock("a", "b", "c");

        Stream<Integer> myIterableHash1 = mapStringToHash(myIterable);
        assertThat(myIterableHash1.count(), is(3L));


        Stream<Integer> myIterableHash2 = mapStringToHash(myIterable);
        assertThat(myIterableHash2.count(), is(3L));
    }

    private MyIterable givenMyIterableMock(String... values) {
        MyIterable myIterable = mock(MyIterable.class);

        Spliterator myIterableSpliterator = Arrays.stream(values)
                .collect(toList())
                .spliterator();
        doReturn(myIterableSpliterator).when(myIterable).spliterator();
        return myIterable;
    }
}

最佳答案

事实证明并没有我想的那么规避。它可以使用自定义的 Answer 实现来完成,但由于 Answer 是一个功能接口(interface),因此以下内容就足够了:

Mockito.when(myIterable.spliterator()).then(invocation -> Arrays.spliterator(values));

关于java - 多次调用时用于 Iterable 实现的模拟拆分器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51168979/

相关文章:

spring - 如何使用 Mockito 在 Spring 中模拟 Autowiring 的 @Value 字段?

unit-testing - Kotlin 中的模拟扩展功能

java - Google Appengine Java 使用哪种 JVM 语言 + Web 框架?

java - 开发和生产测试时的不同 URL

java - 使用mockito进行单元测试时抛出WrongTypeOfReturnValue异常

android - 以编程方式将 id 添加到 R.id

android - 模拟 SharedPreferences.Editor.putString()

java - 使用 bouncycaSTLe 解析证书

java - 如何从 gradle 中的 eclipse .classpath 读取依赖项?

c# - 在测试中使用模拟