lundi 5 octobre 2015

Spock Mock with Guava Collection

I'm having difficulties trying to mock a dependency within 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:-

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(..):-

@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.

However, I wasn't sure how to refactor my spec to make this to work.

How do I go about solving this? Thanks.

Aucun commentaire:

Enregistrer un commentaire