いいえ、HippoMocks はスレッド セーフになるようには設計されていません。
ただし、いくつかの簡単なルールに従えば、マルチスレッド環境でモックを使用できるはずです。
- 1 つのスレッドで順番にセットアップを行い、1 つの MockRepository を使用します。
- 異なるスレッドで異なるモックを使用することは安全です。
- OnCall() セットアップのみを使用する場合、異なるスレッドで 1 つのモックを使用しても安全です。これを OnCall().Do() と組み合わせると、この方法で多くのテストを実行できるはずです。
- 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 で何らかの形でカウントされるためです。
セットアップを同時に実行すると、予想どおりクラッシュします。