0

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

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

- 我也无法更改源或使用模拟库。

4

4 回答 4

3

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

因此,发明一个命名空间,将其命名为mstd. 在您的模拟模式下,这将是您的模拟命名空间。在非模拟模式下,这将只是std.

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

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

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

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

于 2011-07-07T05:38:55.620 回答
2

如果您尝试对类的私有方法进行一些白盒测试,也许您的编译器会让您绕过访问控制?GCC 至少允许-fno-access-control,我在白盒单元测试和数据结构自省(即unordered_{set,map}.

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

于 2011-07-07T04:23:52.110 回答
1

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

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

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

于 2016-03-03T10:19:39.943 回答
0

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

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

于 2011-07-07T02:30:15.270 回答