1

通过以下测试,我有一个无效的存根设置。mockrequestBuilder使用 param 存根"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)
  }
4

2 回答 2

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 {
  ...
}
于 2013-09-05T02:30:28.160 回答
1

虽然我不了解 Scala,但我知道它anyString不会像您认为的那样做。具体来说,所有 Mockito 匹配器都通过副作用工作,将相关的 String 对象添加到ArgumentMatcherStorage我在这个 SO 答案末尾所描述的。

因此,您不能真正将匹配器提取到变量中:

// 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 匹配器来检查你正在检查的参数是否正确形成。这将使您可以灵活地检查您的参数是否大致符合您的预期,同时忽略您不关心的值。

于 2013-09-04T21:40:50.040 回答