gpt4 book ai didi

c++ - GoogleMock 模拟非虚函数

转载 作者:行者123 更新时间:2023-11-30 03:22:09 33 4
gpt4 key购买 nike

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

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

我找到了说明如何使用 模拟非虚函数的文档 hi-perf dependency injection 。但是,尝试如图所示实现它,但没有成功。例如,文档说“将您的代码模板化”。因此,对于我们使用升压 socket 的类(class),我以他们为榜样。我插入:

template <class boost::asio::ip::udp::socket>

这应该让我们插入模拟类而不是具体的 Boost 类。我在类之前尝试过它,并且在接受套接字的构造函数之前分别在头文件和实现文件中尝试过。在每个地方,我都会遇到大量错误,其中大部分都与构造函数调用“没有匹配的函数调用”有关。

很明显,我做错了什么。有谁知道某处的完整示例吗?

更新:根据要求,这是我们目前拥有的:

GoogleMock 模拟非虚函数

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

我为模板定义了一个通用类类型,但这会破坏现有代码。这是我当前的版本:

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));
...

我认为它可能会吐出默认参数,但我不能确定。错误消息不是很有用:

 error: no matching function for call to ‘foonamespace::PIngester::PIngester(boost::asio::io_service&, foonamespace::Band&)’                                     
new PIngester(ioService, band));

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

更新 3

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

最佳答案

正如您所注意到的,问题是编译器无法推断出任何类型 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 PIngester(ioService, band) 中),那么 Socket 会怎样?究竟是?

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


这里有几种方法(可能有很多)来解决这个问题:

  1. 您可以将 PIngester 模板化类本身:

    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));
    ...

    然后调用new PIngester<boost::asio::ip::udp::socket>(ioService, band) (或您的模拟类(class)代替 boost::asio::ip::udp::socket)会起作用。

  2. 您可以定义一个默认模板参数:

    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));
    ...

    然后PIngester(ioService, band)将始终使用此默认的 Boost 类,并且您需要显式传递一些 socket如果您想在测试中使用它,它表示指向您的模拟类的唯一指针。

关于c++ - GoogleMock 模拟非虚函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51408164/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com