繁体   English   中英

Mocking C++ 标准库

[英]Mocking the C++ Standard Library

我在 C++ 中对 class 进行单元测试,一些公共方法称为私有方法。 我知道约定是测试公共接口,但类的功能取决于这些私有方法如何依次调用其他类及其方法。 这类似于公共接口,无论私有 function 发生什么情况,它仍然符合 API。

在大多数情况下,我已经能够模拟私有 function 中调用的类来测试 API,但在少数情况下,我遇到了引用标准库但没有设法模拟它的地方。 mocking 标准库类等有什么技巧吗? 还是我应该跳过它们?

-- 此外,我无法更改源或使用 mocking 库。

为此,我建议您使用 Typemock Isolator++ API,它允许在没有任何重新定义的情况下模拟全局方法。 看,这多么容易:

FAKE_GLOBAL(fopen);
WHEN_CALLED(fopen(0,0)).Return(_anotherFile);

而且您甚至不需要更改源代码。

如果您尝试对类的私有方法进行一些白盒测试,也许您的编译器会让您绕过访问控制? GCC 至少允许-fno-access-control ,我在白盒单元测试和数据结构自省方面都非常成功地使用了它,即 hash 在unordered_{set,map}中的冲突。

如果您真的想狡猾,跳过访问控制还可以让您直接在其他调用之间使用成员变量。

如果您真的希望模拟标准库,那么最简单(可能唯一)的方法是正确检测您的代码。 也就是说,您必须使用中间名称,而不是直接使用标头和std命名空间。

所以发明一个命名空间,称之为mstd 在您的模拟模式下,这将是您的模拟命名空间。 在非模拟模式下,这将只是std的别名。

对于 header 文件,您必须避免直接包含标准头文件,但使用 mocking 层。 因此,您可以包含<mk-map>而不是包含<map> map> 。 这个 header 文件将在标准库和您的版本之间做出决定。 或许是这样的:

#ifdef MOCK_MODE
    #include "mock/map.hpp"
#else
    #include <map>
#endif

您可以交替地为您的编译器提供不同的包含路径,该路径位于标准库之前。 但是,由于无论如何您都必须为命名空间起别名,您仍然必须修改所有代码——因此包含这些特殊标头同样容易。

这是我能看到这个工作的唯一方法。 请注意,使用 LD_PRELOAD 或任何库技术将不起作用:C++ 标准库由许多模板类和内联函数组成。 您需要在编译时立即替换它们。

真的有必要制作标准库的模型吗? 当然,标准库函数可能存在错误,但您的模型可能比实际更可能存在错误。

我会说按原样使用它们。 如果您追踪到标准库的测试失败,那么您就发现了标准库错误。 而且,至少在短期内,您可能必须找到解决此类错误的方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM