web-dev-qa-db-ja.com

gmockで連続したリターンを指定するにはどうすればよいですか?

Mockitoでは、( here から取得)のように複数の戻り値を指定できます。

//you can set different behavior for consecutive method calls.
 //Last stubbing (e.g: thenReturn("foo")) determines the behavior of further consecutive calls.
 when(mock.someMethod("some arg"))
  .thenReturn(new RuntimeException())
  .thenReturn("foo");

 //There is a shorter way of consecutive stubbing:
 when(mock.someMethod()).thenReturn(1,2,3);
 when(mock.otherMethod()).thenThrow(exc1, exc2);

Gmockで作成したモックに複数のリターンを指定する方法はありますか?現在私は持っています:

store_mock_ = std::make_shared<StorageMock>();
ON_CALL(*store_mock_, getFileName(_)).Return("file1").Return("file2");

これは、gmockで複数の戻り値を理解できないため、コンパイルされません。これはgmockで可能ですか?そうでない場合、この問題を解決する別の方法はありますか?次のような複数の戻り値をEXPECTできることがわかりました。

using ::testing::Return;...
EXPECT_CALL(turtle, GetX())
    .WillOnce(Return(100))
    .WillOnce(Return(200))
    .WillOnce(Return(300));

ただし、ON_CALLを使用して複数のリターンをモックするためのドキュメントは見つかりませんでした。

15

ON_CALLは、関数のデフォルトの動作を設定するために使用されます。つまりテスト済みのコードでモック関数が呼び出され、デフォルト値を設定する必要があることはわかっていますが、実際に関数が呼び出される回数は重要ではありません。

  ON_CALL(foo, Sign(_))
      .WillByDefault(Return(-1));
  ON_CALL(foo, Sign(0))
      .WillByDefault(Return(0));
  ON_CALL(foo, Sign(Gt(0)))
      .WillByDefault(Return(1));

希望する動作を得るには、私は expectations を使用します-すでにいくつかの問題の例を提供していますが、もっと表示するために-12を期待する場合の例、その後常に3

  EXPECT_CALL(foo, Sign(_))
      .WillOnce(Return(1))
      .WillOnce(Return(2))
      .WillRepeatedly(Return(3));

EXPECT_CALL "way"は、テストフィクスチャSetUpでこれを設定する場合に問題になる可能性があり、一部のテストではfooを1回だけ呼び出す場合があります。ただし、もちろん、後続の呼び出しのON_CALL戻り値を「制御」する方法はありますが、次の例のように、いくつかの関数の結果を取得するなど、特別なアクションで実行する必要があります。

class IDummy
{
public:
    virtual int foo() = 0;
};

class DummyMock : public IDummy
{
public:
    MOCK_METHOD0(foo, int());
};
using namespace ::testing;
class DummyTestSuite : public Test
{
protected:
    DummyMock dummy;
    void SetUp() override
    {
        ON_CALL(dummy, foo())
           .WillByDefault(
                 InvokeWithoutArgs(this, &DummyTestSuite::IncrementDummy));
    }
    int dummyValue = 0;
    int IncrementDummy()
    {
        return ++dummyValue;
    }

};


TEST_F(DummyTestSuite, aaa)
{
    ASSERT_EQ(1, dummy.foo());
    ASSERT_EQ(2, dummy.foo());
    ASSERT_EQ(3, dummy.foo());

} 
17
PiotrNycz

@PiotrNyczの答えは正解であり、推奨されるソリューションです。

ラムダ関数による代替アプローチmayを使用すると、柔軟性が向上します。

uint32_t callCount = 0;
ON_CALL(*turtle, GetX())
    .WillByDefault(testing::Invoke(
        [&callCount]() -> int {
            return ++callCount * 100;
        }
    ));
3
Roland Ettinger