如何模拟已经编译到库中的类

How to mock classes already compiled into a library?

本文关键字:编译 何模拟 模拟      更新时间:2023-10-16

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

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

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

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

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

免责声明 我在Typemock工作。

使用

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

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

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

重构生产代码

以使其更易于测试时,没有破坏生产代码的风险。

例如:

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

是通过以下方式伪造的:

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

查看更多示例。