Expecting googlemock calls from another thread

后端 未结 5 619
挽巷
挽巷 2021-01-11 11:26

What will be the best way to write (google) test cases using a google mock object and expect the EXPECT_CALL() definitions being called from another thread controlled by the

5条回答
  •  半阙折子戏
    2021-01-11 12:13

    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.

提交回复
热议问题