c++ - 使用谷歌模拟测试 C++ 时无法推断模板参数

标签 c++ unit-testing templates macros googlemock

我的代码使用 Google mock 来测试 EventLogger 类。

首先编译失败是因为编译器没有在宏中找到模板的参数,它没有扣除参数:

candidate: template<class T, class ... Args> auto Filler<traceType>::fill(Args&& ...)
[with T = T; Args = {Args ...}; Class1 traceType = (Class1)1u]
 WRAP_MOCKED_TEMPL_METHOD_1(fill, T);
                            ^
In definition of macro 'WRAP_MOCKED_TEMPL_METHOD_1'
     auto NAME(Args &&...args)\
          ^
Template argument deduction/substitution failed:
     WRAP_MOCKED_TEMPL_METHOD_1(fill, T);

Couldn't deduce template parameter 'T''

所以我尝试在调用函数时显式添加参数(代码中注释//V2)但随后出现了另一个错误消息: filler.fill<Message>(buffer, data, getMessage());

In member function
void EventLogger<traceType>::write(const buffer&, const Message&):
Error: expected primary-expression before '>' token
    `filler.fill<Message>(buffer, data, streamInd);`
                        ^

###代码### 这是我的代码。

类测试

template <Class1 traceType>
class EventLogger
{
public:
    template <typename Message>
    void write(const c1& buffer, const Message& data)
    {
        filler.fill(buffer, data, getMessage());            // V1
        filler.fill<Message>(buffer, data, getMessage());   // V2
    }

private:
    Filler<traceType> filler;
};

模拟类

template <Class1 traceType>
class MockFiller
{
public:
    MOCK_METHOD3(send, void(c1, const Data::SendReq& msg, Class1::StreamInd&));
    MOCK_METHOD3(receive, void(c1, const Data::ReceiveReq& msg, Class1::StreamInd&));

    template <typename Message>
    void fill(c1 buffer, const Message&, Class1::StreamInd& streamInd)
    {
        ASSERT_TRUE(false);
    }
};

可以找到宏MOCK_METHODX的解释在 Google documentation .

MockClass 的特化

template <>
template <>
void MockFiller<Class1::TYPE_1>::fill<Data::SendReq>(c1 buffer,
            const Data::SendReq& msg, Class1::StreamInd& streamInd)
{
    send(buffer, msg, streamInd);
}

template <>
template <>
void MockFiller<Class1::TYPE_1>::fill<Data::ReceiveReq>(c1 buffer,
            const Data::ReceiveReq& msg, Class1::StreamInd& streamInd)
{
    receive(buffer, msg, streamInd);
}

MockFiller 的构造函数

class MockFillerConstructor
{
public:
    MOCK_METHOD0(construct, std::shared_ptr<MockFiller<Class1::TYPE_1>>());
};

在使用其宏测试的类中调用的类

#define WRAP_MOCKED_TEMPL_METHOD_1(NAME, TEMPL) \
template <typename TEMPL, typename ...Args>\
auto NAME(Args &&...args)\
{\
    return this->mock().NAME<TEMPL>(std::forward<Args>(args)...);\
}

template <Class1 traceType>
class Filler : public CopyableMockBase<MockFiller<traceType>>
{
public:
    WRAP_MOCKED_TEMPL_METHOD_1(fill, T);
};

所以我的问题是:

  • 为什么编译器没有自动找到模板参数
  • 为什么我的代码的 V2 包含语法错误

谢谢你的帮助

最佳答案

我对 Google Mock 一无所知,但你的 V2 缺少一个 template关键词:

filler.template fill<Message>(buffer, data, getMessage());   // V2

EventLogger被编译器解析了,不知道是什么Filler<traceType>::fill应该是,是否<接下来是打开模板参数列表或者只是一个小于运算符。没有 template关键字,它假定是后者。

编辑哦,等一下。对于V1,当然不能推导出T .替换宏,您定义 Filler<traceType>::fill像这样:

template <typename T, typename... Args>
auto fill(Args &&...args)
{
    return this->mock().fill<T>(std::forward<Args>(args)...);
}

(另请注意此处 template 中缺失的 this->mock().fill<T>,但这不是重点)。 T未在函数参数列表中引用。编译器将如何推断出它应该是什么?为什么你甚至需要那个 T ?您不能只执行以下操作吗?

template <typename... Args>
auto fill(Args &&...args)
{
    return this->mock().fill(std::forward<Args>(args)...);
}

关于c++ - 使用谷歌模拟测试 C++ 时无法推断模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48173204/

相关文章:

c++ - 为什么当我输入一个大数字时我的计算器程序开始闪烁和滚动

c++ - "struct"和结构成员前缺少 "struct"字有什么区别

unit-testing - 如何在 Node.js 中对请求响应周期进行单元测试?

c++ - 在 C++ 中使用模板特化

c++ - unique_ptr 的默认值

python - 使用 Python 测试非 Python 代码

c# - 模拟副作用

c++ - 无模板优化

c++ - 大小数组作为 C++ 中的函数参数类型

c++ - 编译器错误 : 1 unresolved external