gpt4 book ai didi

c++ - 没有虚拟方法的模拟类

转载 作者:行者123 更新时间:2023-12-02 10:24:03 26 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





Mock non-virtual method C++ (gmock)

(3 个回答)


3年前关闭。




我刚刚开始使用 google mock 对生产代码进行单元测试。我要模拟的类内部没有虚拟方法。通过在 google mock 上阅读一点,就不能模拟这样的类(class)吗?请记住,我不想对源进行任何更改。

class Test
{
Test(void);
virtual ~Test() {}
Add();
};

int Test::Add()
{
return 1;
}

class MockTest : public Test
{
public:
MOCK_METHOD0(Add,int(void));
};

最佳答案

可能有一种方法,但它不如覆盖虚函数的简单方法好。

首先,如果函数不是虚拟的并且是内联的,那么你很可能不走运。当编译器看到对 obj.Add() 的调用时或 ptr->Add() ,该函数不是虚拟的事实意味着它不需要担心除Test::Add()之外的某些函数的可能性。可能需要成为实际调用的那个。因此,它很可能直接内联 Add 定义中的代码。 , 在这种情况下替换它几乎是不可能的,或者它放置了 Test::Add() 的弱链接拷贝放入与调用它的函数相同的目标文件中。在第二种情况下,您可能可以使用链接器技巧替换它,具体取决于您使用的平台 - 直到稍后编译器切换到决定内联它。

如果只是类Test您不想修改,但您可以更改使用 Test 的代码作为依赖项并将通过单元测试进行测试,您可以进行模板依赖项注入(inject)。但是这个问题听起来您可能也不想修改该代码。

现在假设该函数不是内联的,并且在某个文件“Test.cpp”中定义,并且该类是多态的(在示例中是由于虚拟析构函数),您可以替换该文件中的所有定义,以使他们表现得好像他们是虚拟的,即使他们不是:

  • 像往常一样编写 Google Mock 类,使用您希望能够检测到模拟的功能。
    #include "Test.hpp"
    #include <gmock/gmock.h>

    class MockTest : public Test
    {
    public:
    MOCK_METHOD0(Add, int());
    MOCK_CONST_METHOD0(Print, void());
    };

  • (我在示例中添加了一个 const 方法,以展示如何处理它们。)
  • 在相同的单元测试代码中,像这样为模拟函数编写定义。
    int Test::Add()
    {
    if (auto* mock = dynamic_cast<MockTest*>(this))
    return mock->Add();
    // Next comes what to do if the code ever calls Add on
    // a Test which is not actually a MockTest. This could
    // be a stub implementation, an actual implementation, or
    // could intentionally terminate, throw, or note a gtest error.
    ADD_FAILURE() << "Test is not a MockTest";
    return 0;
    }

    void Test::Print() const
    {
    if (auto* mock = dynamic_cast<const MockTest*>(this)) {
    mock->Print();
    return;
    }
    ADD_FAILURE() << "Test is not a MockTest";
    }

  • 您可能还需要至少为 Test.cpp 文件中的其他定义编写 stub ,以使链接器满意。这并不一定意味着它们实际上会被调用或以其他方式使用。
  • 链接单元测试时,请确保未提供真实的 Test.cpp 文件。如果它通常是库的一部分,您可能需要在命令行上列出该库中的其他文件。这可能会导致依赖顺序问题和/或循环依赖问题。 GNU 的链接器具有“-Wl,--start-group ... -Wl,--end-group”来处理循环链接问题,方法是在循环中反复尝试一些对象和/或库,直到尽可能多地得到解决;我不确定其他系统。
  • 关于c++ - 没有虚拟方法的模拟类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54336916/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com