No, HippoMocks is not designed to be thread safe.
However, if you follow some simple rules you should be able to use mocks in a multithreaded environment:
- Do the setup sequentially in one thread and use one single MockRepository.
- Using different mocks in different threads should be safe.
- Using one mock in different threads is safe, when you use only OnCall() setups. Combine it with OnCall().Do() and you should be able do a lot of testing this way.
- Don't use ExpectCall - it is not safe.
UPDATE: Okay, I did it. I wrote a small test for multithreading
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);
}
The result is, that it works fine.
Now I made it a little bit harder and replaced the second OnCall by the following:
for (int i = 0; i< THREAD_ITERATIONS*2; i++)
{
mocks.ExpectCall(im, IMulti::B).Return(i);
}
Here you will get crashes randomly (just play around with the THREAD_ITERATIONS counter). The reason is, that the matched expectations are somehow counted in the Mockrepository.
Doing the setup concurently crashes, as expected.