Mockito 验证字符串集合

Mockito verify Collection of String

我想验证是否将准确的 Collection 传递给模拟方法。 这就是我尝试这样做的方式:

This is a simple example of my real code, which reproduce exactly the same problem.

import com.google.common.collect.Lists;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.mockito.hamcrest.MockitoHamcrest;

import java.util.Collection;

public class MockTest {

    @Test
    void mockTest() {

        final Collection<String> collection = Mockito.mock(Collection.class);

        collection.addAll(Lists.newArrayList("hello"));

        Mockito.verify(collection).addAll(MockitoHamcrest.argThat(Matchers.contains("hello")));
    }
}

但它不起作用,我收到此编译错误:

Error:(20, 35) java: incompatible types: inference variable T has incompatible bounds
    equality constraints: java.lang.Iterable<? extends E>
    lower bounds: java.util.Collection<? extends java.lang.String>,java.lang.Object

知道为什么它不起作用或者我该如何做?

你能试试下面的代码吗

@Test
public void mockTest() {

    final Collection<String> collection = Mockito.mock(Collection.class);

    collection.addAll(Lists.newArrayList("hello"));

    Mockito.verify(collection).addAll((Collection<? extends String>) MockitoHamcrest.argThat(Matchers.contains("hello")));
}

郑重声明,您没有使用此测试测试任何内容,因为您模拟了被测对象。

虽然为了体验,您会遇到此错误,因为 Collection#addAll 方法需要类型为 Collection 的参数,而您提供的类型为 Iterable.

Iterable 对象可能是 Collection 也可能不是,因此编译器无法确保此代码的类型安全。

检查您的模拟方法是否使用正确参数调用的一种方法是使用 ArgumentCaptor.

Collection<String> collection = Mockito.mock(Collection.class);

collection.addAll(Lists.newArrayList("hello"));

ArgumentCaptor<Collection<String>> methodParameterCaptor = ArgumentCaptor.forClass(Collection.class);
Mockito.verify(collection).addAll(methodParameterCaptor.capture()); // same as writing verify(collection, times(1)).add ...
assertThat(methodParameterCaptor.getValue()).containsOnly("hello");