web-dev-qa-db-ja.com

ScalaMock:呼び出しごとに異なる値を返すようにメソッドをモック/スタブする方法は?

ScalaMockを使用して、クラスメソッドをモック/スタブして、呼び出しごとに異なる値を返すようにします(呼び出しの順序が重要です)。

これはmockexpectsで実現できますが、それではこれらの呼び出しを確認する必要があります。

stubでこれを行うことはできますか?

また、「最初にXを返し、次に常にYを返す」(両方ともmockstubを使用)のように言うにはどうすればよいですか?

9
Eyal Roth

はい、これは可能ですが、構文は少し直感的ではありません。

    trait Foo { def getInt: Int }
    val fooStub = stub[Foo]

    (fooStub.getInt _).when().returns(1).noMoreThanOnce()
    (fooStub.getInt _).when().returns(2).noMoreThanOnce()
    (fooStub.getInt _).when().returns(3)
    (fooStub.getInt _).when().returns(4)

    assert(fooStub.getInt == 1)
    assert(fooStub.getInt == 2)
    assert(fooStub.getInt == 3)
    // Note that it's fine that we don't call it a fourth time - calls are not verified.

.once()ではなく.noMoreThanOnce()を使用することが重要です。そうしないと、呼び出しが検証されます。 .noMoreThanTwice()メソッドもありますが、.noMoreThanNTimes()または同等のものはないと思います。


モックとスタブに対して「最初にXを返し、次に常にYを返す」方法は次のとおりです。

    trait Bar { def getString: String }
    val barMock = mock[Bar]

    (barMock.getString _).expects().returning("X")
    (barMock.getString _).expects().returning("Y").anyNumberOfTimes()

    assert(barMock.getString == "X")
    assert(barMock.getString == "Y")
    assert(barMock.getString == "Y")

    val barStub = stub[Bar]

    (barStub.getString _).when().returns("x").noMoreThanOnce()
    (barStub.getString _).when().returns("y")

    assert(barStub.getString == "x")
    assert(barStub.getString == "y")
    assert(barStub.getString == "y")
10
Akzok

私にとって、呼び出しを検証せず、戻り値が入力に依存するモックを作成する最良の方法は、onCallメソッドを使用することです。これは関数のクロージャーを取ります。デフォルトでは、最初の呼び出しのみが処理されるため、必ずanyNumberOfTimesまたはrepreted(...)を追加してください。

_import org.scalamock.scalatest.MockFactory

trait Foo {
  def getSomeValue(param1: Any, param2: Any): String
}

class Test extends MockFactory {
  val fooMock = stub[Foo]

  val it = Iterator.single("X") ++ Iterator.continually("Y")

  (fooMock.getSomeValue _)
    .expects(*, *)
    .onCall((p1, p2) => it.next())
    .anyNumberOfTimes
}
_

これで、fooMock.someValue(...)を最初に呼び出すと、Xと連続する各Yが返されます。

2
botchniaque