加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 如何使用Mockito验证Specs2中特定字符串匹配器的调用

发布时间:2020-12-16 09:54:23 所属栏目:安全 来源:网络整理
导读:我按照这些方针进行测试: httpClient.post(anyString,anyString) returns (first,second)//do my thingthere were two(httpClient).post(anyString,anyString) 这工作正常,但我想验证第一个调用通过与第二个调用不同的主体.身体相当大,我不想在严格的例子上
我按照这些方针进行测试:

httpClient.post(anyString,anyString) returns (first,second)

//do my thing

there were two(httpClient).post(anyString,anyString)

这工作正常,但我想验证第一个调用通过与第二个调用不同的主体.身体相当大,我不想在严格的例子上进行精确匹配.我试过这个:

there was one(httpClientMock).postMessage(anyString,argThat(contain("FOO"))
there was one(httpClientMock).postMessage(anyString,argThat(contain("FOO"))

这让Mockito抱怨??道:

InvalidUSEOfMatchersException: 
 [error] Invalid use of argument matchers!
 [error] 2 matchers expected,3 recorded:

我也尝试过:

there was one(httpClientMock).postMessage(argThat(contain("foo")),argThat(contain("FOO")))
  there was one(httpClientMock).postMessage(argThat(contain("foo")),argThat(contain("FOO")))

这导致:

Wanted 1 time:
 [error] -> ...
 [error] But was 2 times. Undesired invocation: ...

在我看来,这样的事情应该是可能的,但我似乎无法弄明白.见解?

解决方法

我认为这对Mockito而言更是一个问题.当你使用Mockito和specs2并且你有疑问时,请务必下载直接Mockito API:

// simplified httpClient with only one parameter
val httpClient = mock[HttpClient]
httpClient.post(anyString) returns ""

httpClient.post("s1")
httpClient.post("s2")

// forget specs2
// there was two(httpClient).post(anyString)

org.mockito.Mockito.verify(httpClient,org.mockito.Mockito.times(1)).post("s1")

// I guess that you don't want this to pass but it does
org.mockito.Mockito.verify(httpClient,org.mockito.Mockito.times(1)).post("s1")

一种可能的方法是定义一个匹配器来检查参数的连续值:

there was two(httpClient).post(consecutiveValues(===("s1"),===("s2")))

而且连续的值匹配器定义如下:

import matcher._
import MatcherImplicits._

// return a matcher that will check a value against a different
// `expected` matcher each time it is invoked
def consecutiveValues[T](expected: Matcher[T]*): Matcher[T] = {
  // count the number of tested values
  var i = -1

  // store the results
  var results: Seq[(Int,MatchResult[T])] = Seq()

  def result(t: T) = {
    i += 1
    // with Mockito values are tested twice
    // the first time we return the result (but also store it)
    // the second time we return the computed result
    if (i < expected.size) {
      val mr = expected(i).apply(Expectable(t))
      results = results :+ (i,mr)
      mr
     } else results(i - expected.size)._2
  }

  // return a function that is translated to a specs2 matcher
  // thanks to implicits
  // display the failing messages if there are any
  (t: T) => (result(t).isSuccess,results.filterNot(_._2.isSuccess).map { case (n,mr) => 
               s"value $n is incorrect: ${mr.message}" }.mkString(","))
}

您可以测试上面的代码.失败消息不是最好的,但可以解决问题.在这种情况下:

httpClient.post("s1") 
httpClient.post("s2")

there was two(httpClient).post(consecutiveValues(===("s1"),===("s3")))

你会看见:

[error] x test
[error]  The mock was not called as expected: 
[error]  httpClient.post(
[error]      value 1 is incorrect: 's2' is not equal to 's3'
[error]  );
[error]  Wanted 2 times:
[error]  -> at ... 
[error]  But was 1 time:
[error]  -> at ...

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读