Java MockingフレームワークMockitoには、ArgumentCaptor
検証中のメソッドが複数回呼び出されるときに値のリストを蓄積するというユーティリティクラスがあります。
ScalaMockにも同様のメカニズムがありますか?
Specs2では、以下を使用できます。
myMock.myFunction(argument) answers(
passedArgument => "something with"+passedArgument
)
これは、内部でMockitoのArgumentCaptorにマップされます。
ScalaMock3のプレビューリリースでこれを行う内部メカニズムがありますが、現在はクライアントコードに公開されていません。
これのユースケースは何ですか?
ここでwhere
使用またはonCall
文書化することで、必要なことを達成できる場合があります(それぞれ「述語の一致」および「戻り値」の見出しの下)。
Mockito documentationによると、 specs2マッチャーを直接使用できます。
val myArgumentMatcher: PartialFunction[ArgumentType, MatchResult[_]] = {
case argument => argument mustEqual expectedValue
}
there was one(myMock).myFunction(beLike(myArgumentMatcher))
このソリューションの優れた点は、部分関数によって非常に優れた柔軟性が得られることです。引数などでパターン マッチを行うことができます。もちろん、引数の値を比較するだけで十分な場合は、部分関数は必要ありません。
there was one(myMock).myFunction(==_(expectedValue))
もう 1 つのオプションは、既存のマッチャーを拡張して独自の引数キャプターを実装することです。そのようなものでうまくいくはずです(scalamock 3の場合):
trait TestMatchers extends Matchers {
case class ArgumentCaptor[T]() {
var valueCaptured: Option[T] = None
}
class MatchAnyWithCaptor[T](captor: ArgumentCaptor[T]) extends MatchAny {
override def equals(that: Any): Boolean = {
captor.valueCaptured = Some(that.asInstanceOf[T])
super.equals(that)
}
}
def capture[T](captor: ArgumentCaptor[T]) = new MatchAnyWithCaptor[T](captor)
}
その特性をテストクラスに追加することで、この新しいマッチャーを使用できます
val captor = new ArgumentCaptor[MyClass]
(obj1.method(_: MyClass)).expects(capture(captor)).returns(something)
println(captor.capturedValue)