首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何在Scala中模拟带有函数参数的方法?

如何在Scala中模拟带有函数参数的方法?
EN

Stack Overflow用户
提问于 2010-01-28 03:05:48
回答 3查看 14.6K关注 0票数 23

我正在尝试模拟一个接受按名称调用参数的方法调用:

代码语言:javascript
运行
AI代码解释
复制
import org.scalatest.WordSpec
import org.scalatest.mock.MockitoSugar
import org.mockito.Mockito._
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner

trait Collaborator {
   def doSomething(t: => Thing)
}

trait Thing

@RunWith(classOf[JUnitRunner])
class Test extends WordSpec with MockitoSugar {
   "The subject under test" should {
      "call the collaborator" in {
         // setup
         val m = mock[Collaborator]
         val t = mock[Thing]

         // test code: this would actually be invoked by the SUT
         m.doSomething(t)

         // verify the call
         verify(m).doSomething(t)
      }
   }
}

我主要对Mockito感兴趣,因为我正在使用Mockito,但我很有兴趣看看是否有任何主要的模拟框架能够进行这种测试。verify行上的测试在运行时失败,并显示如下错误

参数不同!Test$$anonfun$1$$anonfun$apply$1.apply(Test.scala:27):collaborator.doSomething( ($anonfun$apply$3) );在Test$$anonfun$1$$anonfun$apply$1.apply(Test.scala:24)实际调用时的->具有不同的参数: collaborator.doSomething( ($anonfun$apply$2) );在Test$$anonfun$1$$anonfun$apply$1.apply(Test.scala:24)

处的collaborator.doSomething

如果我没弄错的话,编译器隐式地将t包装在一个返回t的空值函数中。然后,模拟框架将该函数与测试代码中生成的函数进行比较,这是等效的,但不是equals()

我的例子是这个问题的一个相对简单的版本,但我认为这对于任何高阶函数都是一个问题。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-01-28 23:08:34

这看起来很丑陋,但希望它能帮助您找到好的解决方案:

代码语言:javascript
运行
AI代码解释
复制
import org.scalatest.mock.MockitoSugar
import org.mockito.Mockito._

trait Collaborator {
   def doSomething(t: => Thing)
}

trait Thing

new MockitoSugar {
     // setup
     val m = mock[Collaborator]
     val t = mock[Thing]

     m.doSomething(t)

     classOf[Collaborator].getMethod("doSomething", classOf[Function0[_]]).invoke(
        verify(m), 
        new Function0[Thing] { 
            def apply() = null
            override def equals(o: Any): Boolean = t == o.asInstanceOf[Function0[Thing]].apply() 
      })
}
票数 10
EN

Stack Overflow用户

发布于 2013-06-03 02:06:48

你可以试试specs2。在specs2中,我们“劫持”了Mockito Invocation类来解决byname参数:

代码语言:javascript
运行
AI代码解释
复制
trait ByName { def call(i: =>Int) = i }
val byname = mock[ByName]

byname.call(10)
there was one(byname).call(10)
票数 2
EN

Stack Overflow用户

发布于 2010-02-01 10:38:48

这个问题似乎是特定于按名称调用的,因为在常规的高阶函数中,您可以匹配显式的FunctionX对象:

verify(collaborator).somethingElse(any(Function2String,的事情)

在按名称的情况下,将参数包装到Function0中是隐式完成的,Alexey的答案显示了如何使用显式参数调用mock。

您可以编写类似于您自己的验证的代码,它将应用由mockito捕获的参数。

Mockito内部记录调用和它们的参数,例如:http://code.google.com/p/mockito/source/browse/trunk/src/org/mockito/internal/matchers/CapturingMatcher.java

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2152019

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档