1

HippoMocks は、次のように並行テストケース内で使用できますか?

  1. 同期起動フェーズ

    • モックを作成する
    • 期待などを登録します。
  2. 並行テスト段階

    • モックでメソッドを呼び出す
  3. 同期分解フェーズ

    • モックを検証する

この問題に関する明確な声明は見つかりませんでした。あちこちで、非仮想メソッドをモックするとスレッドセーフの可能性が失われることが言及されています ( HippoMocks: 非仮想メソッドをモックすることは可能ですか? ) またはスレッドセーフは非常に簡単に追加できます (残念ながら実際に明らかにすることなく) 。どうやって)。GoogleMock はこの質問に非常に明確に答えます ( https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md#using-google-mock-and-threads )。そのような情報はここで役立ちます。それも。

4

1 に答える 1

2

いいえ、HippoMocks はスレッド セーフになるようには設計されていません。

ただし、いくつかの簡単なルールに従えば、マルチスレッド環境でモックを使用できるはずです。

  1. 1 つのスレッドで順番にセットアップを行い、1 つの MockRepository を使用します。
  2. 異なるスレッドで異なるモックを使用することは安全です。
  3. OnCall() セットアップのみを使用する場合、異なるスレッドで 1 つのモックを使用しても安全です。これを OnCall().Do() と組み合わせると、この方法で多くのテストを実行できるはずです。
  4. ExpectCall は使用しないでください。安全ではありません。

更新:わかりました、やった。マルチスレッド用の小さなテストを書きました

class IMulti
{
public:
    virtual void A() =0;
    virtual int B(int a) = 0;
};

const int THREAD_ITERATIONS = 1000;

static DWORD WINAPI run_thread(LPVOID args)
{
    IMulti* im = static_cast<IMulti*>(args);
    for (int i=0; i<THREAD_ITERATIONS; i++)
    {
        im->A();
        int result = im->B(22);
        std::cout << "task says: " << i <<" result:" << result <<"\n";
    }

    std:: cout << "finished";

    return 0;
}

TEST(check_HippoMocksCanMultiThreadedConcurrentReadingViaOnCall)
{
    MockRepository mocks;

    IMulti* im = mocks.Mock<IMulti>();

    mocks.OnCall(im, IMulti::A);
    mocks.OnCall(im, IMulti::B).Return(4711);

    HANDLE handles[2];

    handles[0] = CreateThread(NULL, 0, &run_thread, im, 0, NULL);
    handles[1] = CreateThread(NULL, 0, &run_thread, im, 0, NULL);

    WaitForMultipleObjects(2, handles, TRUE, INFINITE);
}

その結果、問題なく動作します。ここで、少し難しくして、2 番目の OnCall を次のように置き換えました。

for (int i = 0; i< THREAD_ITERATIONS*2; i++)
{
    mocks.ExpectCall(im, IMulti::B).Return(i);
}

ここでは、ランダムにクラッシュが発生します (THREAD_ITERATIONS カウンターをいじってみてください)。その理由は、一致した期待値が Mockrepository で何らかの形でカウントされるためです。

セットアップを同時に実行すると、予想どおりクラッシュします。

于 2016-08-04T10:11:28.213 に答える