【发布时间】:2020-07-24 10:55:54
【问题描述】:
假设我有这样的事情(非常简单):
case class Foo(bar: String)
val mockFnThatTakesFoo = mock[Foo => Unit]
def fooHasBarSetTo(expectedBar: String, foo: Foo): Boolean = {
val actualBar = foo.bar
actualBar shouldEqual expectedBar
true
}
mockFnThatTakesFoo(argThat(fooHasBarSetTo("blah", _))) wasCalled once
这行得通。但是,断言本身有点复杂,可以使其更具可读性。
我试过这个:
val withFooHavingBarSetTo = (expectedBar: String) => argThat(fooHasBarSetTo(expectedBar, _))
//and then
mockFnThatTakesFoo(withFooHavingBarSetTo("blah")) wasCalled once
更整洁!但不起作用:/
> [info] FooSpec:
[info] - should do stuff *** FAILED ***
[info] org.mockito.exceptions.misusing.InvalidUseOfMatchersException: Invalid use of argument matchers!
[info] 1 matchers expected, 2 recorded:
[info] -> at com.foo.FooSpec.argThat(FooSpec.scala:28)
[info] -> at com.foo.FooSpec.$anonfun$new$5(FooSpec.scala:204)
知道怎么做吗?
【问题讨论】:
-
我不确定我是否理解您要测试的内容。似乎 fooHasBarSetTo 返回一个布尔值,而 mockFnThatTakesFoo 需要一个 foo。它是如何编译的?您能否详细说明您要测试的内容?您可以尝试使用 mockito 的验证方法。 programcreek.com/scala/org.mockito.Mockito.verify
-
fooHasBarSetTo是一个帮助断言传递给mockFnThatTakesFoo的参数的函数。这就是 mokito 的argThat的工作方式,它接受一个函数,该函数接受测试函数 (mockFnThatTakesFoo) 的参数,并返回 true 以通过或 false 以使断言失败。 site.mockito.org/javadoc/current/org/mockito/… -
就像我说的,这过于简单化了。在实践中,我使用这种方法来测试我的服务所依赖的模拟 finagle 服务。因此,
fooHasBarSetTo等效项将采用调用服务模拟的参数,反序列化正文缓冲区等,并对此进行更详细的断言。 -
你是对的。但是 argThat,至少在 scala 中,需要一个您不覆盖的 ArgumentMatcher。我有点确定我理解你正在测试的场景。你测试的方法是什么?
-
argThat可以接受一个简单地接受参数并返回布尔值的函数。在文档中查看下方。
标签: scala mockito scalatest mockito-scala