GMock:如何返回由 EXPECT_CALL() 定义的函数指针

fex*_*fex 3 c++ lambda googletest googlemock

我正在使用一个将函数指针作为void*. 我想要一个模拟返回一个函数指针,并且我想要就地定义该函数(如 lambda;它不起作用,如下所示)。

下面显示了一个最小的工作示例。

#include <gtest/gtest.h>
#include <gmock/gmock.h>

using namespace std;
using namespace testing;

class Original
{
public:
    typedef int(*fptr)();

    void Func() 
    {
        void* f = Func2();
        fptr func = reinterpret_cast<fptr>(f);
        if (func) {
            int i = func();
            if (i == 1) {
                //do something
            } else if (i == 3) {
                //NOTE my unit test should test this decision branch
            }
        }
    }

    static int Func3() {return 1;}

    virtual void* Func2() {return (void*)&Func3;}
};

class MyMock : public Original
{
public:
    MOCK_METHOD0(Func2, void*());
};
Run Code Online (Sandbox Code Playgroud)

我的主要目标:我想摆脱这个函数,并在EXPECT_CALL(). 见下文。

int MockFunc() {cout << "mock func" << endl; return 3;}
Run Code Online (Sandbox Code Playgroud)

测试用例:

TEST(MYTEST, Test)
{
    MyMock m;

    //WORKS: compiles and works as expected, 
    //but I do not want to use **MockFunc**
    EXPECT_CALL(m, Func2()).Times(AtLeast(1))
        .WillRepeatedly(Return(&MockFunc)); 

    //DOES NOT WORK: Does not compile, of course 
    //(compiler message below this code block)
    EXPECT_CALL(m, Func2()).Times(AtLeast(1))
        .WillRepeatedly(Return((void*)&([](){return 3;}))); 
    m.Func();
}
Run Code Online (Sandbox Code Playgroud)

main.cpp:117:90: 错误:获取临时地址 [-fpermissive]

为了完整起见,main()

int main(int argc, char** argv)
{    
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
Run Code Online (Sandbox Code Playgroud)

那么问题又来了:我怎样才能摆脱该MockFunc()函数并在 中就地定义其内容Return()

sky*_*ack 6

以下语句应该有效:

EXPECT_CALL(m, Func2()).Times(AtLeast(1)).WillRepeatedly(Return((void*)(+([](){return 3;}))));
Run Code Online (Sandbox Code Playgroud)

它利用了非捕获 lambda 衰减为函数指针的事实。
换句话说,表达式的结果类型(+([](){return 3;})int(*)()。然后您可以void*像以前一样将其投射到。该错误也应该消失,因为您不再获得临时地址。