通过以下测试,我的存根设置无效。模拟requestBuilder
使用参数"INCORRECT"
存根,而被测试的类则使用"/socket"
调用它。
我在JUnit中使用Mockito的经验告诉我,运行时的调用将导致null
。但是,我看到了误报。测试通过& requestBuilder
正在返回模拟request
,即使它是使用"/socket"
调用的。
这是为什么?是否与多个期望有关?如果是这样,最终的期望是重要的,应失败。
class ChannelSpec extends Specification with Mockito with ScalaCheck with ArbitraryValues { def is = s2"""
A Channel must
send an open request to /socket with provided channel name on instantiation $sendToSocket
"""
def sendToSocket = prop{(name: String, key: Key, secret: Secret) =>
val requestBuilder = mock[(String, Seq[Map[String, String]]) => Req]
val request = mock[Req]
val httpRequestor = mock[(Req) => Future[String]]
val result = mock[Future[String]]
val params = Seq(Map("key" -> key.value, "timestamp" -> anyString, "token" -> anyString), Map("channel" -> name))
requestBuilder("INCORRECT", params) returns request
httpRequestor(request) returns result
new Channel(name, key, secret, requestBuilder = requestBuilder, httpRequestor = httpRequestor)
there was one(requestBuilder).apply("INCORRECT", params)
println("expecting " + request)
there was one(httpRequestor).apply(request)
}
答案 0 :(得分:1)
虽然我不了解Scala,但我知道anyString
没有按照您的想法行事。具体来说,all Mockito matchers work through side effects,正如我在this SO answer末尾所描述的那样,将相关的String对象添加到ArgumentMatcherStorage
。
因此,您无法真正将匹配器提取为变量:
// This is fine, because the parameters are evaluated in order.
takesTwoParameters(eq("A"), eq("B")) returns bar
// Now let's change it a little bit.
val secondParam = eq("SECOND")
val firstParam = eq("FIRST")
// At this point, firstParam == secondParam == null, and the hidden argument
// matcher stack looks like [eq("SECOND"), eq("FIRST")]. That means that your
// stubbing will apply to takesTwoParameters("SECOND", "FIRST"), not
// takesTwoParameters("FIRST", "SECOND")!
takesTwoParameters(firstParam, secondParam)) returns bar
此外,您不能将anyString
嵌套到Seq或Map等任意类型中; Mockito的参数匹配器旨在匹配整个参数。
您最好的选择是使用argThat
作为参数,并创建一个小的Hamcrest匹配器,检查您正在检查的参数是否正确形成。这将使您可以灵活地检查您的参数是否与您期望的大致相同,而忽略了您不关心的值。
答案 1 :(得分:1)
我认为这只是一种表现形式,在接受规范中,没有例外表明失败的期望。所以你有:
def test = {
1 === 2
1 === 1
}
然后test
将通过,因为只有最后一个值将保留为测试结果。您可以通过链接期望来改变这种行为:
def test = {
(1 === 2) and
(1 === 1)
}
或者通过在规范中混合ThrownExpectations
特征:
import org.specs2.Specification
import org.specs2.matcher.ThrownExpectations
import org.specs2.mock.Mockito
class MySpec extends Specification with ThrownExpecations with Mockito {
...
}