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

标签 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;
};

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

现在我正在尝试对我的 Person 类进行单元测试,我需要一种方法来模拟/ stub Destroy 方法。我想我可以围绕静态 Destroy 函数编写一个包装器类,然后使用依赖注入(inject)将这个包装器注入(inject)到 Person 类中,但是仅仅调用这个函数似乎有点矫枉过正简单的类。什么是简单直接的方法来做到这一点?或者依赖注入(inject)真的是最好的方法吗?

更新

最终我决定创建一个类来包装所有第 3 方库的全局函数,然后使用依赖注入(inject)将此类传递到我的个人类的构造函数中。这样我就可以清除 Destroy 方法。虽然 person 类只使用一个函数,但库的其他函数在我的代码中的其他点被调用,并且当我需要测试这些函数时,我会面临同样的问题。

我在我的主应用程序代码中创建了这个包装器类的单个实例,并将其注入(inject)到需要的地方。我选择走这条路是因为我觉得这样更清晰。我喜欢 Billy ONeal 的解决方案,我认为它回答了我的问题,但我意识到如果我离开代码几个月然后回来,与依赖注入(inject)相比,我会花更长的时间来弄清楚发生了什么。我想起了 Python 的格言“显式优于隐式”。而且我觉得依赖注入(inject)使正在发生的事情更加明确。

最佳答案

创建链接接缝。将您的销毁声明放在 header 中,然后有两个实现文件:

// Destroy.cpp
void Destroy()
{
    //Code that really does destruction
}

并用于测试:

// DestroyFake.cpp
void Destroy()
{
    //Code that does fake destruction
}

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

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

关于c++ - 模拟静态/全局函数的最佳简单方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6542208/

相关文章:

python - 如何使用日期时间对方法进行单元测试?

r - 解码 R 中的函数

c++ - 为什么声明了枚举的 C++ 类的大小为 1?

c++ - 使用模板实现 "visitor pattern"

c++ - 库包 pcre-8.37 中的文件 pcre.h 在哪里

unit-testing - 我无法 mock 类(class)的属性(property)

c++ - std::make_pair: "cannot convert ‘int*’ 到 ‘std::pair<EndPointAddr*, EndPointAddr*>*’ 初始化”

java - 使用 spring-test-mvc 进行 Spring Controller 单元测试失败

javascript - 全局上下文 - 检查未定义

c++ - 如何在 C 或 C++ 中使用未命名的函数参数