模拟静态/全局函数的最简单方法?

Use*_*ser 9 c++ unit-testing function mocking static-functions

我有一个像Person这样简单的类似于值的类:

class Person
{
public:
    Person(ThirdPartyClass *object);
    virtual ~Person(void);

    virtual std::string GetFullName() const;
    virtual int GetAge() const;
    virtual int GetNumberOfDaysTillBirthday() const;
};
Run Code Online (Sandbox Code Playgroud)

我正在使用第三方库,ThirdPartyClass需要有一个名为Destroy(第三方库的一部分)的全局/静态函数来调用它来销毁它.Destroy在Person析构函数中调用此函数.

现在我正在尝试对我的Person类进行单元测试,我需要一种模拟/存根Destroy方法的方法.我想我可以围绕静态Destroy函数编写一个包装类,然后使用依赖注入将这个包装器注入到Person类中,但这样做只是为了在这个简单的类上调用这个函数似乎有些过分.什么是简单直接的方法呢?或者依赖注入真的是最好的方法吗?

更新

最终我决定创建一个包含所有第三方库的全局函数的类,然后使用依赖注入将此类传递给我的person类的构造函数.这样我就可以删除Destroy方法.虽然person类只使用单个函数,但是在我的代码中的其他点调用库的其他函数,因为我需要测试那些我将面临同样问题的函数.

我在主应用程序代码中创建了这个包装类的单个实例,并在需要的地方注入它.我选择走这条路是因为我觉得它更清楚.我喜欢Billy ONeal的解决方案,我认为它回答了我的问题,但我意识到如果我要将代码保留几个月并且回来,我会花更长的时间来弄清楚与依赖注入相比发生了什么.我想起了蟒蛇格言的禅语"明确比隐含更好".而且我觉得依赖注入使得发生的事情变得更加明确.

Bil*_*eal 10

创建一个链接缝.将您的destroy声明放在标题中,然后有两个实现文件:

// Destroy.cpp
void Destroy()
{
    //Code that really does destruction
}
Run Code Online (Sandbox Code Playgroud)

并进行测试:

// DestroyFake.cpp
void Destroy()
{
    //Code that does fake destruction
}
Run Code Online (Sandbox Code Playgroud)

然后将第一个文件链接到主二进制文件,将第二个文件链接到测试二进制文件.

除此之外,你要求的是不可能的.链接器将对全局函数和静态方法的调用绑定到直接跳转到被调用者代码中 - 没有查找或决策过程来创建任何类型的重载,就像你正在寻找的那样(除了Destroy调用更容易的东西之外)嘲笑).


小智 5

简单,使用Typemock Isolator ++(免责声明-我在那工作)

在测试中添加1行以假/模拟 Destroy

全球使用:

FAKE_GLOBAL(Destroy);
Run Code Online (Sandbox Code Playgroud)

公共静态使用:

WHEN_CALLED(Third_Party::Destroy()).Ignore();
Run Code Online (Sandbox Code Playgroud)

私有静态使用:

PRIVATE_WHEN_CALLED(Third_Party::Destroy).Ignore();
Run Code Online (Sandbox Code Playgroud)

不需要额外的代码/没有条件的代码/没有其他链接。