scalamock:子类型上的通配符参数匹配

scalamock: Wildcard argument match on subtype

在我的 class 中,我有两个版本的方法。一个拿 Exception,另一个拿 String.

class Foo {
  def method(e: Exception) = ???
  def method(s: String) = ???
}

JMock 中,我可以根据方法的类型模拟对方法的调用。请注意,我使用 Exception 的子类型来具体说明我在测试中的期望。

context.checking(new Expectations() {{              
    oneOf(mock).method(with(any(SubTypedException.class)));
}}

而在Scalamock中,我可以使用通配符来匹配

(mock.method(_: Exception)).expects(*).once

当我尝试匹配特定子类型时,以下代码无法编译(我意识到这在 Scala 中没有意义)。

// doesn't compile    
(mock.method(_: SubTypedException)).expects(*).once

如何将 JMock 中的 with(any(SubTypesException.class)) 转换为 Scalamock?我可以想象使用谓词匹配 (where),这是要走的路吗?

Edit: Thinking about it, the JMock with(any(SubTypedException)) is more about keeping the compiler happy and expressing intent. As I understand it, the Matcher is an IsAnything matcher so won't actually fail a test if a different type of exception is thrown.

So, it may be asking a bit much of Scalamock to both capture the intent and fail the test under the right circumstance. Bonus points in explaining how to do something like instanceOf in Scalamock.

首先:以下不编译,因为类型归属只是为了帮助(静态)重载解析。该行没有任何特定于 Scalamock 的内容:

(mock.method(_: SubTypedException))

要测试参数的运行时类型,您可以使用在 ScalaMock 3.2.1 中引入的 ArgThat 和辅助函数:

import scala.reflect.ClassTag

def typedArg[T, U : ClassTag]: ArgThat[T] = new ArgThat[T]({
  case x: U => true
  case _ => false
})

(mock.method(_: Exception)).expects(typedArg[Exception, SubTypedException])