如何模拟Google Test中公共方法正在使用的类中的私有方法?

问题描述 投票:3回答:2

我有一个班级,比如ClassA,它有一些公共功能和私人。公共函数转换为类私有函数。现在我的意图是通过公共函数测试私有函数。对于Public函数,我试图调用原始实现,对于私有方法,我试图创建一个Mock函数。

我的A级是这样的,

class ClassA {
public:
    string getName(string key) {
        int value = 2;
        int code = getCode(value);
        if(code != 2)
             cout<<"Error";
        else
             return "XYZ";
    }

private:
    int getCode(int value) {
        if(value == 2)
             return 2;
        else
             return -1;
    }
};

现在我像这样对ClassA进行了模拟,

class MockA : public ClassA {
       public:
       MOCK_METHOD1(getName,string(string key)); //Mock for public method
       MOCK_METHOD1(getCode,int(int value))l //Mock for private method
}

这是我的GoogleTest测试用例,

TEST(ClassATest, Test1)
{
    MockA a;
    Class a1;

    EXPECT_CALL(a,getCode()).Times(1).WillOnce(Return(2));
    EXPECT_CALL(a,getName()).Times(1).WillOnce(Return(Invoke(&a1, 
ClassA::getName());
}

正如您所看到的,对于私有方法,我使用mock和public方法,我使用Invoke并调用原始实现。

现在,当我编译这段代码时,我收到一个错误,

实际函数调用计数与EXPECT_CALL(a,getCode())不匹配....预期:被调用一次实际:从未调用 - 未满足且处于活动状态

现在当我尝试使用原始的实现来获取getCode()时,

EXPECT_CALL(a,getCode()).Times(1).WillOnce(Return(Invoke(&a1, 
ClassA::getCode());

我得到一个编译错误,说getCode()是不可访问的,我认为是预期的。

到现在为止,如果你正在读这篇文章,希望你能理解我的问题陈述。我必须通过传递不同的参数来测试私有方法,通过我通过gtest测试的公共方法。

我想模仿github中的this文章所述的私有方法,并为我的公共方法调用orininal生产代码。

我做了一些根本错误的事吗?如果是这样,你们中的任何人都可以使用更好的方法来处理我的用例

我尝试过FRIEND_TEST和tbh,我不想在我的生产代码中进行任何修改。我会尝试这作为最后的手段。

c++ googletest gmock
2个回答
1
投票

您正在尝试从ClassA调用私有方法。这是不可能的,除非有朋友声明,但是,它不是理想的。

问题源于您的测试设计应该调用公共API而不是实现细节。


0
投票

迟到的答案,但我目前正在研究类似的问题,并看到了这个问题。

在你的例子中,我不太清楚Invoke()的目的是什么,但如果你要做的就是验证对getCode()的调用并控制它的返回值,那么你只需要模拟那个。

您必须修改生产代码以使私有功能成为虚拟,所以如果这不是一个选项,那么当然这对您不起作用。这似乎是一个非常安全的修改。

class ClassA {
public:
    string getName(string key) {
        int value = 2;
        int code = getCode(value);
        if (code != 2)
            return "Error";
        return "XYZ";
    }

private:
    virtual int getCode(int value) {
        if (value == 2)
            return 2;
        return -1;
    }
};

class MockA : public ClassA {
public:
    MOCK_METHOD1(getCode, int(int value));
};

TEST(ClassATest, Test1)
{
    MockA mockA;
    EXPECT_CALL(mockA, getCode(2)).WillOnce(Return(2));
    EXPECT_EQ(mockA.getName("key"), "XYZ");
}
© www.soinside.com 2019 - 2024. All rights reserved.