【问题标题】:Spock Mock with Guava CollectionSpock Mock 与 Guava 系列
【发布时间】:2015-10-05 15:58:18
【问题描述】:

我在尝试模拟 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 函数。

但是,我不确定如何重构规范以使其正常工作。

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

【问题讨论】:

    标签: java unit-testing mocking guava spock


    【解决方案1】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2015-07-10
      • 2013-12-29
      • 2016-06-23
      • 1970-01-01
      • 2018-03-09
      • 2014-05-15
      • 1970-01-01
      • 2016-09-07
      • 1970-01-01
      相关资源
      最近更新 更多