我运行测试时模拟匹配器的问题

问题描述

我是 Mockito 的新手,我正在处理一个非常奇怪的匹配器问题

def fetchById[T: Format](elasticDetails: ESDetails): F[ESResult[T]]

我的 Elastic 搜索客户端有这个定义,问题始于通用格式:T,我必须在那里传递。

        .fetchById[JsValue](anyObject[ESDetails])
        .returns(IO.pure(ESResult(200,value = Some(fakeResponse)))) ```



org.mockito.exceptions.misusing.InvalidUSEOfMatchersException: 
Invalid use of argument matchers!
2 matchers expected,1 recorded:
-> at org.specs2.mock.mockito.MockitoMatchers.anyObject(MockitoMatchers.scala:49)

This exception may occur if matchers are combined with raw values:
    //incorrect:
    someMethod(anyObject(),"raw String");
When using matchers,all arguments have to be provided by matchers.
For example:
    //correct:
    someMethod(anyObject(),eq("String by matcher"));```


//This the error for matchers that i'm getting after I run my tests.

解决方法

您将 Format[T] 的真实实例与 Matcher 的假 ESDetails 实例一起隐式传递。 Mockito 要求所有参数要么是真实实例要么是匹配器,并且不允许您混合使用它们,正如您在此错误消息中看到的那样。

最简单的解决方法是将隐式参数转换为匹配器,例如

.fetchById[JsValue](anyObject[ESDetails])(eq(implicitly[Format[T]]))

另见What precisely is a scala evidence parameterHow to stub a method call with an implicit matcher in Mockito and Scala

正如 Mateusz 所提到的,使用 scalamock 可能比 Mockito 更好,因为它可以更好地处理这种情况,因为它是为 Scala 设计的。