【问题标题】:How to use gmock to mock up a std::function?如何使用 gmock 模拟 std::function?
【发布时间】:2017-03-01 00:18:52
【问题描述】:

我的类的构造函数是

A( ...
   std::function<bool(const std::string&, const std::string&)> aCallBack, 
   ... );

我想使用 EXPECT_CALL 来测试它。这个回调来自另一个 B 类。我创建了一个 Mock 喜欢

class BMock : public B
{
    MOCK_METHOD2( aCallBack, bool(const std::string&, const std::string&) );
}

然后我尝试了

B *b = new B();
std::function<bool(const std::string&, const std::string&)> func = 
    std::bind(&B::aCallBack, b, std::PlaceHolders::_1, std::PlaceHolders::_2);

还是不行。如何获取 gmock 对象的函数指针?

谢谢!!

【问题讨论】:

    标签: unit-testing testing tdd googletest googlemock


    【解决方案1】:

    如果你想使用mock来跟踪调用并设置返回值,你可以使用MockFunction

    using testing::_;
    using testing::MockFunction;
    using testing::Return;
    
    MockFunction<bool(const std::string&, const std::string&)> mockCallback;
    
    EXPECT_CALL(mockCallback, Call(_, _)).WillOnce(Return(false)); // Or anything else you want to do
    
    A( ...
       mockCallback.AsStdFunction()
       ...);
    
    

    【讨论】:

    • 这是黄金。在多个相关的堆栈溢出帖子中寻找这个,你的答案是我发现的第一个提到 MockFunction 并提供了一个完整的例子。
    • 我不确定为什么文档中从未提及这一点。我错过了什么吗?
    • 不幸的是,所有MockFunctions 在错误消息中都被标识为Call,这非常无益...
    【解决方案2】:

    通过单元测试,您应该只测试您的 A 类,因此您的测试应该只检查传递给构造函数的 any 函数是否被调用。 所以你不需要模拟,而只需传递一个 lambda,它只用布尔值(或计数器)记录。

    bool gotCalled = false;
    A a( [&gotCalled]( const std::string&, const std::string& ) { gotCalled = true; return true; } );
    ...
    ASSERT_TRUE( gotCalled );
    

    【讨论】:

    • 无论如何,虽然将函数传递给构造函数很好,但从架构上讲,如果将其用作回调,它的味道就不对了。一般来说,最好将它传递给实际使用它的函数。
    • 此答案与 TS 问题的实际解决方案无关,实际答案请查看 Enzam 的答案
    猜你喜欢
    • 1970-01-01
    • 2020-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-21
    相关资源
    最近更新 更多