简体   繁体   English

Spock Mock with Guava Collection

[英]Spock Mock with Guava Collection

I'm having difficulties trying to mock a dependency within Guava Collection. 我在尝试模拟Guava Collection中的依赖项时遇到困难。

Let's assume I have a following code to test: 假设我有以下代码要测试:

@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();
    }
}

My Spock Spec looks like this: 我的Spock Spec看起来像这样:

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']
    }
}

This spec runs just fine and it is doing what I want it to do. 该规范运行得很好,并且可以满足我的要求。

Then I refactored my implementation to use Guava's Collections2.transform(..) :- 然后,我重构实现以使用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);
            }
        });
    }
}

When I rerun my spec, I'm getting this error:- 重新运行规格时,出现此错误:-

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

My take is it has something to do with the mocking timing because the Guava function will only be executed when the collection is used. 我认为这与模拟时间有关,因为Guava函数仅在使用集合时才会执行。

However, I wasn't sure how to refactor my spec to make this to work. 但是,我不确定如何重构规格以使其正常工作。

How do I go about solving this? 我该如何解决呢? Thanks. 谢谢。

Under the hood transform() method returns TransformedCollection class. 在底层, transform()方法返回TransformedCollection类。 As you can see here transformation is applied no sooner than on iterating the wrapped collection. 正如您在这里看到的那样仅在迭代包装的集合时才应用转换。 Since you don't iterate the transformed collection mocked service is not invoked and no interaction is recorded. 由于您不进行迭代,因此不会调用转换后的集合模拟服务,因此不会记录任何交互。

It seems that simply iterating the collection should solve the problem, however such test should be really well documented. 似乎简单地对集合进行迭代就可以解决问题,但是这种测试应该有充分的记录。

Another way is using FluentIterable.from(list).transform(function).toList() instead of Collections2.transform(list, function) . 另一种方法是使用FluentIterable.from(list).transform(function).toList()代替Collections2.transform(list, function)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM