Mockito拒绝将TypeSafeMatcher与通用方法API配对

Ela*_*da2 1 java unit-testing mocking mockito java-8

我想测试调用某些API的代码:

public <T extends MessageLite> ApiFuture<String> publish(final T message) throws Exception {
}


public <T extends MessageLite> ApiFuture<String> publish(final T message, final ApiFutureCallback<T> futureCallback) throws Exception {
}


public <T> String publishSynchronous(final String message, final ApiFutureCallback<T> futureCallback) throws Exception {
}
Run Code Online (Sandbox Code Playgroud)

在我的测试中,我使用了嘲笑模拟,然后我想验证它是否被具有字段的原型对象(扩展了MessageLite)调用 isSuccess = false

我已经厌倦了这段代码:

    verify(customPublisher, times(0)).publish(isFailureResult(), anyObject());
Run Code Online (Sandbox Code Playgroud)

和这个匹配器:

public class FailResultMatcher extends TypeSafeMatcher<MessageLite> {

    @Override
    protected boolean matchesSafely(final MessageLite sentResult) {
        return !((SdkResult)sentResult).getIsSuccess();
    }


    public static FailResultMatcher isFailureResult() {
        return new FailResultMatcher();
    }

    @Override
    public void describeTo(final Description description) {

    }
}
Run Code Online (Sandbox Code Playgroud)

但我在测试编译中遇到错误:

Error:(131, 42) java: no suitable method found for publish(com.w.sdkService.matchers.FailResultMatcher,java.lang.Object)
    method linqmap.cloud.google.pubsub.CustomPublisher.<T>publish(java.lang.String,com.google.api.core.ApiFutureCallback<T>) is not applicable
      (cannot infer type-variable(s) T
        (argument mismatch; com.w.sdkService.matchers.FailResultMatcher cannot be converted to java.lang.String))
    method linqmap.cloud.google.pubsub.CustomPublisher.<T>publish(T) is not applicable
      (cannot infer type-variable(s) T
        (actual and formal argument lists differ in length))
    method linqmap.cloud.google.pubsub.CustomPublisher.<T>publish(T,com.google.api.core.ApiFutureCallback<T>) is not applicable
      (inferred type does not conform to upper bound(s)
        inferred: com.w.sdkService.matchers.FailResultMatcher
        upper bound(s): com.google.protobuf.MessageLite)
Run Code Online (Sandbox Code Playgroud)

我怎样才能解决这个问题?

Mor*_*fic 6

根据文档(Mockito 1Mockito 2),您必须使用argThat(matcher)Mockito匹配器,该匹配器允许您使用自定义参数匹配器:

 //stubbing
 when(mock.giveMe(argThat(new MyHamcrestMatcher())));

 //verification
 verify(mock).giveMe(argThat(new MyHamcrestMatcher()));
Run Code Online (Sandbox Code Playgroud)

您没有说要使用Mockito 1还是2,但是想法很相似,只是静态导入有所不同:

  • 1 :(import static org.mockito.Matchers.argThat;或为简单起见org.mockito.Mockito而扩展Matchers
  • 2: import static org.mockito.hamcrest.MockitoHamcrest.argThat;

奖金提示,为了便于阅读,您可以将替换times(0)never(),因此在您的情况下为:

verify(customPublisher, never()).publish(argThat(isFailureResult()), anyObject());
Run Code Online (Sandbox Code Playgroud)