首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >非虚拟函数的GoogleMock仿真

非虚拟函数的GoogleMock仿真
EN

Stack Overflow用户
提问于 2018-07-18 17:48:35
回答 1查看 1.2K关注 0票数 1

我们正在为现有的代码库编写单元测试。我们使用Google /Google进行测试,C++11和Eclipse与gcc编译器一起使用。

我们的一个类聚合一个Boost套接字。它使用它作为一个实例,但幸运的是,我们可以修改现有的代码库,我将它更改为一个指针,并将套接字作为依赖项注入。所以我开始模拟对套接字的调用,但是有一个问题: Boost函数是非虚拟的。

我找到了一些说明如何使用https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md#mocking-non-virtual-methods-mockingnonvirtualmethods模拟非虚拟函数的文档。然而,如图所示,试图实现它却没有成功。例如,doc说要“临时修改代码”。因此,对于使用boost套接字的类,我遵循了它们的示例。我插入:

代码语言:javascript
复制
template <class boost::asio::ip::udp::socket>

这应该让我们插入模拟类,而不是具体的Boost类。我在类之前和在接受套接字的构造函数之前,在头文件和实现文件中分别尝试了它。在每一个地方,我都会得到大量的错误,其中大多数都是按照构造函数调用“不匹配函数调用”的方式进行的。

很明显,我做错了什么。有人知道什么地方有完整的例子吗?

更新:每个请求的,下面是我们目前拥有的内容:

非虚拟函数的GoogleMock仿真

代码语言:javascript
复制
class PIngester : public IPIngester{
public:
    // this is the method that takes the socket. It is the constructor, and the socket
    // is a default parameter so the existing code will still work. We added the socket 
    // as a parameter specifically for unit testing. If no socket is provided, the 
    // constructor creates one. It only will ever create a concrete Boost
    // Socket, not a mock one.
    PIngester(boost::asio::io_service& ioService, Band band,
              std::unique_ptr<boost::asio::ip::udp::socket> socket = std::unique_ptr<boost::asio::ip::udp::socket>(nullptr));
    ...

更新2

我为模板定义了一个泛型类类型,但这破坏了现有代码。以下是我目前的版本:

代码语言:javascript
复制
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));
    ...

我认为这可能是对默认参数的限制,但我不能确定。错误消息没有多大帮助:

代码语言:javascript
复制
 error: no matching function for call to ‘foonamespace::PIngester::PIngester(boost::asio::io_service&, foonamespace::Band&)’                                     
          new PIngester(ioService, band));

此错误消息来自现有代码;它似乎不识别默认参数。

更新3

我已经放弃了这种方法,决定编写一个Boost套接字包装器。包装器将保存实际的套接字实例,其方法将直接传递到实际套接字。包装器的函数将是虚拟的,我的模拟对象将从包装器继承。然后,我的模拟对象将模拟包装器的虚拟函数。

EN

回答 1

Stack Overflow用户

发布于 2018-07-18 21:05:02

正如您注意到的,问题是编译器不能推断出Socket在这里表示的任何类型:

代码语言:javascript
复制
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 PIngester(ioService, band)),那么Socket到底是什么呢?

现在,在调用构造函数时无法显式指定任何模板参数,因此,如果构造函数被模板化了,就不能执行类似new PIngester<boost::asio::ip::udp::socket>(ioService, band)的操作。

以下是几种解决这一问题的方法(可能有很多):

  1. 您可以临时处理PIngester类本身: 模板类PIngester : public IPIngester{ public: PIngester(boost::asio::io_service& ioService,Band band,std::unique_ptr socket = std::unique_ptr(nullptr));. 然后调用new PIngester<boost::asio::ip::udp::socket>(ioService, band) (或者用模拟类代替boost::asio::ip::udp::socket)就可以工作了。
  2. 可以定义默认模板参数: 类PIngester : public IPIngester{ public: PIngester(boost::asio::io_service& ioService,Band band,std::unique_ptr socket = std::unique_ptr(nullptr));. 然后,PIngester(ioService, band)将始终使用这个默认的Boost类,如果要在测试中使用这个类,则需要显式地传递一些表示指向模拟类的唯一指针的socket
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51408164

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档