如何根据头文件中定义的代码测试类

How to test classes depending on code only defined in header files?

本文关键字:定义 代码 测试类 文件 何根      更新时间:2023-10-16

我开始在c++中进行单元测试,并试图找出最佳实践。然而,今天我在编写使用boost进程间的代码时遇到了瓶颈,特别是只在头文件中定义的file_mapping和mapped_region。

我的一般问题是:如何测试类取决于代码只定义在头文件(即Boost和STL)?

的例子:假设我创建了一个这样的类MyClass.h:

#pragma once
#include <stddef>
namespace boost { namespace interprocess {
class mapped_region;
}}
class MyClass
{
public:
    MyClass(mapped_region& mapped_region);
    std::size_t get_size() const;
private:
    boost::interprocess::mapped_region& mapped_region_;
}

MyClass.cpp文件:

#include "MyClass.h"
#include <boost/interprocess/mapped_region.hpp>
using namespace boost::interprocess;
MyClass::MyClass(mapped_region& mapped_region)
: mapped_region_(mapped_region) {}
std::size_t MyClass::get_size() const
{
    return mapped_region_.get_size();
}

如何去测试MyClass::get_size()?由于mapped_region只在头文件中实现,它将创建一个基本上独立于其他对象文件的对象文件(也就是说,不需要链接),因此创建一个假对象或模拟对象不会,因为它不能被链接。

我能看到工作的唯一方法是在。cpp中使用#ifdefs,并在MyClass.cpp中做类似的事情:

#ifdef RUN_UNITTEST
#include "my_fake_mapped_region.h"
#else
#include <boost/interprocess/mapped_region.hpp>
#endif

但是这看起来像是一个可怕的黑客,并且用测试感染了生产代码。

我猜可以在测试代码中使用boost,但这需要在磁盘上创建文件,并且从技术上讲它不再是单元测试,而是集成测试?(对不起,如果我错了术语)。

如果你能给我一些关于这件事的见解,我将非常感谢。

创建典型抽象层的方法是将有问题的库包装在一个非常薄的层后面,然后将该层注入到需要它的对象的构造函数中。您已经理解,包装每个boost函数会将使用boost变成使用一堆复杂的非标准包装器。

正如您所发现的,您不能简单地从库中继承接口,因为声明包含实现,因为正是实现给您带来了问题。

诀窍在于认识到不必包装每个boost模板。您只需要包装那些给您带来"难以设置"answers"难以测试"的问题。boost::interprocess是那些难以测试的问题之一,所以它值得一个包装器。

请记住,您不应该在这里尝试测试boost。单元测试不会(也不应该)关心它是建立了一个真正的内存映射还是调用了一个虚假的内存映射,只要调用看起来有效,测试就可以继续进行。您也不需要测试您创建的包装器,只要它们很薄,您就可以轻松地验证它们不包含逻辑。例如,我不会测试MyMemoryRegionWrapper::get_size()方法,因为目测显示它只是返回返回值。