Expecting googlemock calls from another thread

Using lambdas, you could do something like (I have put boost equivalents in comments):

TEST_F(BarTest, DoSomethingWhenFunc2Gt0)
{
    std::mutex mutex;                  // boost::mutex mutex;
    std::condition_variable cond_var;  // boost::condition_variable cond_var;
    bool done(false);

    EXPECT_CALL(fooInterfaceMock, func1())
        .Times(1);
    EXPECT_CALL(fooInterfaceMock, func2())
        .Times(1)
        .WillOnce(testing::Invoke([&]()->int {
            std::lock_guard<std::mutex> lock(mutex);  // boost::mutex::scoped_lock lock(mutex);
            done = true;
            cond_var.notify_one();
            return 1; }));

    bar.start();
    bar.triggerDoSomething();
    {
      std::unique_lock<std::mutex> lock(mutex);               // boost::mutex::scoped_lock lock(mutex);
      EXPECT_TRUE(cond_var.wait_for(lock,                     // cond_var.timed_wait
                                    std::chrono::seconds(1),  // boost::posix_time::seconds(1),
                                    [&done] { return done; }));
    }
    bar.stop();
}

If you can't use lambdas, I imagine you could use boost::bind instead.


Fraser's answer inspired me for a simple solution using a GMock specialized Action. GMock makes it very easy to quickly write such Actions.

Here's the code (excerpt from BarTest.cpp):

// Specialize an action that synchronizes with the calling thread
ACTION_P2(ReturnFromAsyncCall,RetVal,SemDone)
{
    SemDone->post();
    return RetVal;
}

TEST_F(BarTest, DoSomethingWhenFunc2Gt0)
{
    boost::interprocess::interprocess_semaphore semDone(0);
    EXPECT_CALL(fooInterfaceMock,func1())
        .Times(1);
    EXPECT_CALL(fooInterfaceMock,func2())
        .Times(1)
        // Note that the return type doesn't need to be explicitly specialized
        .WillOnce(ReturnFromAsyncCall(1,&semDone));

    bar.start();
    bar.triggerDoSomething();
    boost::posix_time::ptime until = boost::posix_time::second_clock::universal_time() +
            boost::posix_time::seconds(1);
    EXPECT_TRUE(semDone.timed_wait(until));
    bar.stop();
}

TEST_F(BarTest, DoSomethingWhenFunc2Eq0)
{
    boost::interprocess::interprocess_semaphore semDone(0);
    EXPECT_CALL(fooInterfaceMock,func1())
        .Times(1);
    EXPECT_CALL(fooInterfaceMock,func2())
        .Times(1)
        .WillOnce(Return(0));
    EXPECT_CALL(fooInterfaceMock,func3(Eq(5)))
        .Times(1)
        // Note that the return type doesn't need to be explicitly specialized
        .WillOnce(ReturnFromAsyncCall(true,&semDone));

    bar.start();
    bar.triggerDoSomething();
    boost::posix_time::ptime until = boost::posix_time::second_clock::universal_time() +
            boost::posix_time::seconds(1);
    EXPECT_TRUE(semDone.timed_wait(until));
    bar.stop();
}

Note the same principle will work well for any other kind of semaphore implementation as boost::interprocess::interprocess_semaphore. I'm using it for testing with our production code that uses it's own OS abstraction layer and semaphore implementation.


So I liked these solutions, but thought it might be easier with a promise, I had to wait for my test to startup:

std::promise<void> started;
EXPECT_CALL(mock, start_test())
    .Times(1)
    .WillOnce(testing::Invoke([&started]() {
        started.set_value();
    }));
system_->start();
EXPECT_EQ(std::future_status::ready, started.get_future().wait_for(std::chrono::seconds(3)));