模拟C ++标准库

时间:2011-07-07 01:29:15

标签: c++ unit-testing mocking standard-library c++-standard-library

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

我已经能够模拟私有函数中调用的类,大部分用于测试API,但在少数情况下,我遇到了标准库被引用的地方,并且没有设法模拟它。模拟标准库类等有什么技巧吗?或者我应该跳过它们?

- 此外,我无法更改源代码或使用模拟库。

4 个答案:

答案 0 :(得分:1)

如果您正在尝试对类的私有方法进行一些白盒测试,那么您的编译器可能会绕过访问控制吗? GCC至少允许-fno-access-control,我已经非常成功地使用了whitebox单元测试和对数据结构的内省,即unordered_{set,map}中的哈希冲突。

如果确实想要狡猾的话,跳过访问控制还可以让你直接在其他调用之间删除成员变量。

答案 1 :(得分:1)

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

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

对于头文件,您必须避免直接包含标准头,但使用模拟层。因此,您可以包含<map>,而不是包含<mk-map>。然后,此头文件将在标准库和您的版本之间进行决定。也许是这样的:

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

您可以交替地为编译器提供一个不同的包含路径,一个在标准库之前的路径。但是,由于您必须为命名空间添加别名,因此您仍然需要修改所有代码 - 因此包含这些特殊标题也同样容易。

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

答案 2 :(得分:1)

出于这样的目的,我建议您使用Typemock Isolator++ API,它允许模拟全局方法而无需重新定义。 看,它有多容易:

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

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

答案 3 :(得分:0)

是否真的有必要制作标准库的模型?当然,标准库函数可能存在错误,但您的模型可能更容易出现错误。

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