C++ GoogleMock模拟非虚拟函数
我们正在为现有的代码库编写单元测试。我们正在使用GoogleTest/GoogleMock进行测试,C++11和EclipseCDT以及gcc编译器 我们的一个类聚合了一个Boost套接字。它将其用作实例,但幸运的是我们可以修改现有的代码库,我将其更改为指针,并将套接字作为依赖项注入。所以我开始模拟对套接字的调用,但有一个问题:Boost函数是非虚拟的 我找到了显示如何使用模拟非虚拟函数的文档。然而,试图实现它(如图所示)是不成功的。例如,文档说“模板化您的代码”。因此,对于使用boost套接字的类,我遵循了他们的示例。我插入:C++ GoogleMock模拟非虚拟函数,c++,unit-testing,c++11,googlemock,C++,Unit Testing,C++11,Googlemock,我们正在为现有的代码库编写单元测试。我们正在使用GoogleTest/GoogleMock进行测试,C++11和EclipseCDT以及gcc编译器 我们的一个类聚合了一个Boost套接字。它将其用作实例,但幸运的是我们可以修改现有的代码库,我将其更改为指针,并将套接字作为依赖项注入。所以我开始模拟对套接字的调用,但有一个问题:Boost函数是非虚拟的 我找到了显示如何使用模拟非虚拟函数的文档。然而,试图实现它(如图所示)是不成功的。例如,文档说“模板化您的代码”。因此,对于使用boost套接字
template <class boost::asio::ip::udp::socket>
此错误消息来自现有代码;它似乎无法识别默认参数
更新3
我放弃了这种方法,决定编写一个Boost套接字包装器。包装器将保存实际的套接字实例,其方法将直接传递到实际的套接字。包装器的函数将是虚拟的,我的模拟对象将从包装器继承。然后,我的mock对象将模拟包装器的虚拟函数。正如您所注意到的,问题是编译器无法推断出此处要表示的任何类型的
Socket
:
class PIngester : public IPIngester{
public:
template <class Socket>
PIngester(boost::asio::io_service& ioService, Band band,
std::unique_ptr<Socket> socket = std::unique_ptr<Socket>(nullptr));
...
然后调用new pingster(ioService,band)
(或者用模拟类代替boost::asio::ip::udp::socket
)就可以了
class PIngester : public IPIngester{
public:
template <class Socket = boost::asio::ip::udp::socket>
PIngester(boost::asio::io_service& ioService, Band band,
std::unique_ptr<Socket> socket = std::unique_ptr<Socket>(nullptr));
...
类pingster:公共ipinger{
公众:
模板
PIngester(boost::asio::io_服务和IOS服务、频带、,
std::unique_ptr socket=std::unique_ptr(nullptr));
...
然后,PIngester(ioService,band)
将始终使用这个默认的Boost类,如果您想在测试中使用它,您需要显式地传递一些表示模拟类的唯一指针的socket
您能告诉我们到目前为止是如何设置的吗?对我来说,
template
似乎是将模板参数定义为函数定义的一部分(在这种情况下,您应该定义一个通用类名,而不是boost::asio::ip::udp::socket
)。如果您试图根据Google Mock文档传入模板参数,我希望看到类似TestFunction()的内容
相反。好的,添加了。如果我理解正确,我只需要在需要在生产代码中使用具体类和在测试中使用模拟类的情况下对其进行模板化?我认为这不会是一个问题,因为我只在未传入套接字时在构造函数中实例化具体类,而生产代码已经传入了。我我总是通过模拟测试。这些都是很好的建议,谢谢!我会给他们一个机会。我试过了,但就像一个九头蛇一样,我砍下了一个头,又出现了两个。现在gcc说我不能将模板类型作为成员数据。没关系;我将编写一个Boost套接字包装器,它具有直接传递到实际B的虚拟函数oost套接字。我的模拟对象将从包装器继承,并模拟其虚拟函数。这主意不错;这是处理第三方类的好方法。
error: no matching function for call to ‘foonamespace::PIngester::PIngester(boost::asio::io_service&, foonamespace::Band&)’
new PIngester(ioService, band));
class PIngester : public IPIngester{
public:
template <class Socket>
PIngester(boost::asio::io_service& ioService, Band band,
std::unique_ptr<Socket> socket = std::unique_ptr<Socket>(nullptr));
...
template <class Socket>
class PIngester : public IPIngester{
public:
PIngester(boost::asio::io_service& ioService, Band band,
std::unique_ptr<Socket> socket = std::unique_ptr<Socket>(nullptr));
...
class PIngester : public IPIngester{
public:
template <class Socket = boost::asio::ip::udp::socket>
PIngester(boost::asio::io_service& ioService, Band band,
std::unique_ptr<Socket> socket = std::unique_ptr<Socket>(nullptr));
...