【问题标题】:How to mock classes already compiled into a library?如何模拟已经编译到库中的类?
【发布时间】:2015-06-18 15:24:23
【问题描述】:

我们的代码库包含一组组件。每个组件都包含内置于静态库中的独立项目形式的“通用”/可重用代码。组件示例:UI 小部件、容器、网络等。

当我为我们的 UI 小部件编写单元测试时,我实际上是在构建一个链接到“UI Widgets”静态库的可执行文件。

当涉及到模拟时,这会使事情变得复杂。我读过的普通模拟方法(依赖注入/控制反转)的演示方式在被模拟的代码已经编译时似乎很难(如果不是不可能的话)。

如果我的 UI Widgets 静态库包含大约 20 个类的实现,我可能只需要模拟其中的 5 个。所以我需要以某种方式告诉我的测试可执行文件使用静态库中的 15 个符号,但忽略 5 个(并支持另一个库中的模拟实现,或者理想情况下直接编译到测试可执行文件中)。

如何有效地模拟静态库中的类?我可以通过使用运行时多态性 + 接口模式想出一些方法来做到这一点,但是我也希望能够使用模板进行模拟。仅基于我的项目结构,在这里使用模板对我来说似乎更遥不可及。

【问题讨论】:

    标签: c++ unit-testing mocking


    【解决方案1】:

    免责声明我在 Typemock 工作。

    使用模板和多态性进行“模拟”会迫使您调整生产代码以适应您的测试,例如在您通常不会这样做的地方添加冗余的间接级别和使用接口,有时会破坏您的原始设计。

    引入新的类和接口(需要维护),最终使您的代码变得更大、更不可读并且不像您希望的那样简单,从而使您的代码变得复杂。

    Typemock Isolator++ 解决了这个问题,使您能够在运行时模拟任何东西(*抽象类、非虚拟、静态、非公共、c 函数等...),在与生产代码分开的库中进行测试。

    在重构生产代码以使其更具可测试性时,不会有破坏生产代码的风险。

    例如:

    class MyClass
    {
       int GetResult() { return -1; }
    }
    

    是通过以下方式伪造的:

    MyClass* fakeMyClass = FAKE<MyClass>();
    WHEN_CALLED(fakeMyClass->GetResult()).Return(10);
    

    查看更多examples

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-18
      • 1970-01-01
      相关资源
      最近更新 更多