我的实际用例是涉及finagle FuturePool
的单元测试代码:我想确保实际调用了FuturePool.apply
,以便在正确的池实例中执行任务。
然而,我遇到的问题似乎更通用,所以我将在一个抽象的例子中说明它,与finagle或future无关。
假设我有这两个类:
class Foo {
def apply(f: => String) = f
}
class Bar(val foo: Foo) {
def doit(f: => String) = foo(f)
}
Bar
有一个Foo
的实例,它知道如何运行函数,我想测试它实际上是用它来执行的:
describe("Bar") {
it("should use the right foo") {
val foo = mock[Foo]
when(foo.apply(any)).thenAnswer( new Answer[String] {
def answer(invocation: InvocationOnMock): String =
invocation.getArgumentAt(0, classOf[Function0[String]]).apply()
})
new Bar(foo).doit("foo") should equal("foo")
}
}
这不起作用:.doit
显然是返回null,因为mockito没有意识到它被嘲笑了。在这种情况下,any
似乎与Function0
不匹配(将其替换为any[Function0[String]]
也无济于事。
我也尝试了另一种方式:
it("should Foo!") {
val foo = Mockito.spy(new Foo)
new Bar(foo).doit("foo") should equal("foo")
verify(foo).apply(any)
}
这也行不通,有点证实了我怀疑any
在这种情况下没有工作:
Argument(s) are different! Wanted:
foo$1.apply(
($anonfun$apply$mcV$sp$7) <function0>
);
Actual invocation has different arguments:
foo$1.apply(
($anonfun$apply$mcV$sp$6) <function0>
);
有关解决这个问题的好方法吗?
答案 0 :(得分:0)
此签名:
def apply(f: => String)
被称为“按名称调用”,它传递表达式而不是计算表达式。这对于Scala非常具体,并且没有得到Mockito的支持。
有很多解决方法:
one by Eric看起来最简单,你可能想要什么。