如何使用 gtest 模拟 C++ 中的非虚方法?

问题描述 投票:0回答:1

是否有一种干净、简单的方法可以使用 gtest 来模拟 C++ 中的非虚拟方法?尽管使用GoogleMock方式迫使你重新声明你的模拟类。

在我看来,这个功能对于在 C++ 中充分发挥 BDD、TDD 和模拟的潜力至关重要。我目前正在使用 FakeIt 但我仍然遇到这些困难 :

  • 无需使用虚拟方法即可测试代码
  • 在不影响当前代码的情况下测试遗留代码

编辑: 我发现 Injector++isolate++ 这似乎是很好的解决方案,但不是跨平台的。

c++ mocking tdd bdd fakeit
1个回答
0
投票

模拟非虚拟类从一开始就对我来说很痛苦,我想模拟一个类(虚拟和非虚拟方法)而不触及生产代码,因此不需要为每个类模板化或创建接口。
这就是你可以做到的。

诀窍是用模拟类替换感兴趣的类。 那么该怎么做呢?

假设您有一个名为

Production
的生产类,并且您想要测试该类,但它依赖于另一个名为
Dependency
的类,该类没有接口或虚拟方法。您需要模拟它才能测试
Production
类。

在 Production.h 中,所有包含语句注入以下代码后

#if TESTENV
    #include "DependencyMock.h"
    #define Dependency DependencyMock
#endif

因此,如果

TESTENV
已定义并处于活动状态,您将包含该类的模拟版本,并将文件中
Dependency
类的所有用法替换为
DependencyMock
类。

DependencyMock.h 可能看起来像这样:

#pragma once
#include "Dependency.h"

class DependencyMock
{
public:
    void nonVirtualMethodToMock() {...};
    int methodToWrap() { return dep_.methodToWrap(); }
private:
    Dependency dep_;
};

您可以模拟任何和所有方法,但只包装您可以使用的方法可能会更容易、更好。

对生产代码 .h 文件的侵入也最小,我们并没有真正更改生产代码,我们只是在测试时更改它。

因此,在我看来,唯一的缺点是,要使其工作,您需要重新编译要模拟的类才能运行测试。

这是 CmakeLists.txt 示例:

add_executable(testProduction  
    testProduction.cpp
    Production.cpp
    DependencyMock.cpp

)
target_link_libraries(testProduction PRIVATE
    ${PRODUCTION_DEPEND_LIBS}
    gtest_main
)
target_compile_definitions(testPoduction PRIVATE -DTESTENV=ON)

你就可以走了。

我不知道这是如何扩展的,因为我没有编写那么多测试,但现在它对我来说已经足够了,并且是迄今为止我所见过的最简单的方法(我没有使用任何平台,如 Isolator 或 Injector) 。 所以希望这有帮助:)

© www.soinside.com 2019 - 2024. All rights reserved.