java - Spock Mock 与 Guava Collection

标签 java unit-testing mocking guava spock

我在尝试模拟 Guava Collection 中的依赖项时遇到困难。

假设我有以下代码要测试:

@Service
public final class ServiceA {

    private final ServiceB serviceB;

    @Autowired
    public ServiceA(ServiceB serviceB) {
        this.serviceB = serviceB;
    }

    public Collection<String> runAll(Collection<String> dataList) {
        final ImmutableList.Builder<String> builder = ImmutableList.builder();

        for (String data : dataList) {
            builder.add(serviceB.run(data));
        }

        return builder.build();
    }
}

我的 Spock 规范如下所示:

class ServiceASpec extends Specification {
    def serviceB = Mock(ServiceB.class)
    def serviceA = new ServiceA(serviceB)

    def "test"() {
        when:
        def strings = serviceA.runAll(['data1', 'data2'])

        then:
        1 * serviceB.run('data1') >> 'result1'
        1 * serviceB.run('data2') >> 'result2'
        0 * _._

        strings == ['result1', 'result2']
    }
}

这个规范运行得很好,它正在做我想要它做的事情。

然后我重构了我的实现以使用 Guava 的 Collections2.transform(..):-

@Service
public final class ServiceA {

    private final ServiceB serviceB;

    @Autowired
    public ServiceA(ServiceB serviceB) {
        this.serviceB = serviceB;
    }

    public Collection<String> runAll(Collection<String> dataList) {
        return Collections2.transform(dataList, new Function<String, String>() {
            @Override
            public String apply(final String input) {
                return serviceB.run(input);
            }
        });
    }
}

当我重新运行我的规范时,我收到此错误:-

Too few invocations for:

1 * serviceB.run('data1') >> 'result1'   (0 invocations)

Unmatched invocations (ordered by similarity):

None

Too few invocations for:

1 * serviceB.run('data2') >> 'result2'   (0 invocations)

Unmatched invocations (ordered by similarity):

None

我的看法是它与模拟计时有关,因为 Guava 函数仅在使用集合时才会执行。

但是,我不确定如何重构我的规范以使其发挥作用。

我该如何解决这个问题?谢谢。

最佳答案

引擎盖下transform()方法返回 TransformedCollection类(class)。如您所见here转换在迭代包装集合时立即应用。由于您不迭代转换后的集合,因此不会调用模拟服务,也不会记录任何交互。

似乎简单地迭代集合就可以解决问题,但是这样的测试应该有很好的记录。

另一种方法是使用 FluentIterable.from(list).transform(function).toList() 而不是 Collections2.transform(list, function)

关于java - Spock Mock 与 Guava Collection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32952827/

相关文章:

python - 如何在 Django 中模拟 View 装饰器

testing - 使用 Angularjs 和 requirejs 时在测试中注入(inject)

java - 网址格式错误异常

java - 如何以编程方式设置内容类型?获取 org.jvnet.mimepull.MIMEParsingException : Missing start boundary

java - 在 Akka 中记录收到的消息

java - 使用反射来了解字段和相对值

javascript - 如何在 JavaScript 中使用 Math.random 进行测试?

javascript - 使用页面重新加载和 iframe 对 JS 应用程序进行单元测试

javascript - headless 运行 Google Closure 测试套件

java - PowerMockito : mock private method to throw private class