首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用googlemock实现非虚函数的假蕴涵

用googlemock实现非虚函数的假蕴涵
EN

Stack Overflow用户
提问于 2016-11-03 17:54:41
回答 1查看 1.9K关注 0票数 2

我有一些基于googlemock框架的单元测试遗留代码。当我试图用一些新的场景扩展单元测试时,我遇到了以下问题:

代码语言:javascript
复制
class D
{
public:
  void pubMethod1();
  int pubMethod2();
  // There are pretty much non-virtual methods, both public and private
  ...
protected:
  uint method3();
  void method4();
  ...
  // Some class members are here
};

class SUT
{
public:
  ...
protected:
   D _dep;
};

SUT类(被测试的软件)应该进行测试,它的实现是在文件sut.cpp中定义的。SUT依赖于D类,其实现在文件d.cpp中。为了减少链接器的依赖,我不想将d.cpp添加到测试中,因此在链接测试时,会出现许多针对D成员的“未定义符号”错误。为了筛选错误并提供可预测的行为,我将在我的测试中为D的方法创建假实现。然而,直到D的方法是虚拟的,我仍然无法使用它与googlemock的所有功能。

我喜欢使用googlemock框架中的WillOnce、AtLeast、WillRepeatedly、Invoke等函数,因为它使单元测试创建更加容易。问题是我不喜欢改变D的界面,把它的方法变成虚拟的。我要为D的方法创建的假实现是否可以使用googlemock函数呢?

注意:我已经考虑过带有模板SUT类的解决方案,但是我想知道是否还有其他解决方案。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-11-04 02:57:37

首先-最好是重新设计你的SUT类,让D通过一些抽象的界面注入。因为我在下面描述的解决办法确实很棘手,所以在将来不容易维护和理解.

如果你要在UT目标中伪造你的D类,那么你可以为D:DMock制作Mock类。这个DMock不会与D相关--不是从它派生出来的--但是它需要与真实/假的D对象配对。

所以-看看这个例子:

创建模拟D接口的DMock (请注意,您应该只模拟公共函数),因为SUT只使用公共函数:

代码语言:javascript
复制
class DMock 
{
public:
    MOCK_METHOD0(pubMethod1, void ());
    MOCK_METHOD0(pubMethod2, int ());
};

将您的真实(但却是假的)D对象与DMock对象配对--如下所示:

代码语言:javascript
复制
class DMockRepo
{
public:
    // for UT
    void addMockToUse(DMock* dMock) { freeMock.push_back(dMock); }

    // for implementing D fake methods
    DMock& getMock(D* original)
    {
        // TODO: use more sophisticated way to add mock to map...
        if (not usedMock[original])
        {
           usedMock[original] = freeMock.front();
           freeMock.pop_front();
        }
        return *useddMock[original];
    }
    static DMockRepo& getInstance() { return instance; } //singleton
private:
    DMockRepo() {} // private
    static DMockRepo instance;
    std::map<D*,DMock*> usedMock;
    std::deque<DMock*> freeMock; 
};

使用模拟创建D类公共方法的假实现:

代码语言:javascript
复制
void D::pubMethod1()
{
    DMockRepo::getInstance().getMock(this).pubMethod1();
} 
// 

非公开的方法是无关紧要的-所以你想做什么就做什么.

并使用DMockRepo对D对象设置期望:

代码语言:javascript
复制
TEST(Usage,Example)
{
   DMock dMock;
   DMockRepo::getInstance().addMockToUse(&dMock);
   SUT sut; // you should know how many D objects SUT needs - I assume just one

   EXPECT_CALL(dMock, pubMethod1());
   sut.doSomethingThatCallsDpubMethod1();
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40408227

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档