Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 伪造的google模拟委托必须是可复制的_C++_Googletest_Googlemock - Fatal编程技术网

C++ 伪造的google模拟委托必须是可复制的

C++ 伪造的google模拟委托必须是可复制的,c++,googletest,googlemock,C++,Googletest,Googlemock,使用GoogleTest和mocks,如果函数返回对数据对象的引用,我似乎无法将来自mock的调用委托给fake。我使用的谷歌测试版本是1.10.0版本,来自发布的zip 在下面的代码中,当我从一个模拟委托给一个伪代理时,我会得到一个错误,指示复制ctor被删除。是,必须删除此代码才能正常工作 对于返回类引用的函数,是否有任何方法可以使用gmock将模拟委托给伪函数 请注意,在下面的代码中,有一个宏: #定义使用模拟访问器1 这用于测试所需的测试代码执行路径。 将该值定义为零只会测试Access

使用GoogleTest和mocks,如果函数返回对数据对象的引用,我似乎无法将来自mock的调用委托给fake。我使用的谷歌测试版本是1.10.0版本,来自发布的zip

在下面的代码中,当我从一个模拟委托给一个伪代理时,我会得到一个错误,指示复制ctor被删除。是,必须删除此代码才能正常工作

对于返回类引用的函数,是否有任何方法可以使用gmock将模拟委托给伪函数

请注意,在下面的代码中,有一个宏:
#定义使用模拟访问器1
这用于测试所需的测试代码执行路径。 将该值定义为零只会测试AccessorImpl类的行为是否正确。我这样做是为了检查我没有在这个类中对类和实例进行错误格式化。 谢谢你的意见

#include "gtest/gtest.h"
#include "gmock/gmock.h"

#include <cstdint>

using ::testing::Invoke;
using ::testing::Mock;
using ::testing::Return;
using ::testing::ReturnRef;
using ::testing::_;

class Accessor
{
public:
    virtual ~Accessor()                  = default;
    Accessor()                           = default;
    Accessor(Accessor const&)            = delete;
    Accessor(Accessor&&)                 = delete;
    Accessor& operator=(Accessor const&) = delete;
    Accessor& operator=(Accessor&&)      = delete;

    struct Foo
    {
        ~Foo()                     = default;
        Foo()                      = default;
        Foo(Foo const&)            = delete;
        Foo(Foo&&)                 = delete;
        Foo& operator=(Foo const&) = delete;
        Foo& operator=(Foo&&)      = delete;

        uint32_t thing_1 = 13u;
    };

    struct Bar
    {
        ~Bar()                     = default;
        Bar()                      = default;
        Bar(Bar const&)            = delete;
        Bar(Bar&&)                 = delete;
        Bar& operator=(Bar const&) = delete;
        Bar& operator=(Bar&&)      = delete;

        uint32_t thing_2 = 79u;
    };

    virtual Foo&       GetFoo()       = 0;
    virtual Bar const& GetBar() const = 0;
};

class AccessorImpl: public Accessor
{
public:
    ~AccessorImpl() override                       = default;
    AccessorImpl()                                 = default;
    AccessorImpl(AccessorImpl const& ) = delete;
    AccessorImpl(AccessorImpl&&)                   = delete;
    AccessorImpl& operator=(AccessorImpl const&)   = delete;
    AccessorImpl& operator=(AccessorImpl&&)        = delete;

    Foo&       GetFoo()       override { return this->foo_; };
    Bar const& GetBar() const override { return this->bar_; };

private:
    Foo foo_;
    Bar bar_;
};

#define USE_MOCK_ACCESSOR 1
#if USE_MOCK_ACCESSOR
class MockAccessor : public Accessor
{
public:
    MOCK_METHOD0(GetFoo, Foo&());
    MOCK_CONST_METHOD0(GetBar, Bar&());
};

class MockAccessorWithFake : public MockAccessor
{
public:
    MockAccessorWithFake() : MockAccessor(), fake_accessor_()
    {
        ON_CALL(*this, GetFoo).WillByDefault([this]() {
            return this->fake_accessor_.GetFoo();
        });

        ON_CALL(*this, GetBar).WillByDefault([this]() {
            return this->fake_accessor_.GetBar();
        });
    }

private:
    AccessorImpl fake_accessor_;
};
#endif

TEST(AccessorTest, test)
{
#if USE_MOCK_ACCESSOR
    MockAccessorWithFake accessor;
#else
    AccessorImpl accessor;
#endif
    EXPECT_EQ(accessor.GetFoo().thing_1, 13u);
    EXPECT_EQ(accessor.GetBar().thing_2, 79u);
}
#包括“gtest/gtest.h”
#包括“gmock/gmock.h”
#包括
使用::testing::Invoke;
使用::testing::Mock;
使用::测试::返回;
使用::testing::ReturnRef;
使用::测试::;
类访问器
{
公众:
virtual~Accessor()=默认值;
Accessor()=默认值;
存取器(存取器常数&)=删除;
访问器(访问器&&)=删除;
访问器和运算符=(访问器常量&)=删除;
访问器和运算符=(访问器和运算符)=删除;
结构Foo
{
~Foo()=默认值;
Foo()=默认值;
Foo(Foo const&)=删除;
Foo(Foo&&)=删除;
Foo&运算符=(Foo const&)=删除;
Foo&运算符=(Foo&&)=删除;
uint32_t thing_1=13u;
};
结构条
{
~Bar()=默认值;
Bar()=默认值;
Bar(Bar const&)=删除;
条形图(条形图&&)=删除;
Bar&运算符=(Bar const&)=删除;
条形图&运算符=(条形图&&)=删除;
uint32_t thing_2=79u;
};
虚拟Foo&GetFoo()=0;
虚拟条常量&GetBar()常量=0;
};
类访问器MPL:公共访问器
{
公众:
~AccessorImpl()override=默认值;
AccessorImpl()=默认值;
AccessorImpl(AccessorImpl const&)=删除;
AccessorImpl(AccessorImpl&&)=删除;
AccessorImpl&运算符=(AccessorImpl const&)=删除;
AccessorImpl&operator=(AccessorImpl&&)=删除;
Foo&GetFoo()重写{返回此->Foo;};
Bar const&GetBar()const override{返回此->Bar;};
私人:
富富!;
酒吧酒吧;
};
#定义使用\u模拟\u访问器1
#如果使用\u MOCK\u访问器
类MockAccessor:公共访问器
{
公众:
模拟方法0(GetFoo,Foo&());
模拟常量方法0(GetBar,Bar&());
};
类MockAccessorWithFake:public MockAccessor
{
公众:
MockAccessor with fake():MockAccessor(),fake_accessor
{
ON_CALL(*this,GetFoo).WillByDefault([this](){
返回此->伪访问器.GetFoo();
});
ON_CALL(*this,GetBar).WillByDefault([this](){
返回此->伪访问器.GetBar();
});
}
私人:
附件mpl伪附件;
};
#恩迪夫
测试(访问测试,测试)
{
#如果使用\u MOCK\u访问器
使用假访问器模拟访问器;
#否则
附加器MPL附加器;
#恩迪夫
EXPECT_EQ(accessor.GetFoo().thing_1,13u);
EXPECT_EQ(accessor.GetBar().thing_279u);
}
来自clang编译器的错误:

test_accessor.cc:83:20: error: call to deleted constructor of 'Accessor::Foo'
            return this->fake_accessor_.GetFoo();
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~

test_accessor.cc:26:9: note: 'Foo' has been explicitly marked deleted here
        Foo(Foo const&)            = delete;
        ^

test_accessor.cc:82:46: error: no viable conversion from '(lambda at
      test_accessor.cc:82:46)' to 'const Action<Accessor::Foo &()>'
        ON_CALL(*this, GetFoo).WillByDefault([this]() {
                                             ^~~~~~~~~~

googletest-src/googlemock/include/gmock/gmock-actions.h:339:7: note: candidate constructor (the implicit copy constructor) not viable:
      no known conversion from '(lambda at test_accessor.cc:82:46)' to 'const testing::Action<Accessor::Foo &()> &' for 1st argument
class Action {
      ^

googletest-src/googlemock/include/gmock/gmock-actions.h:339:7: note: candidate constructor (the implicit move constructor) not viable:
      no known conversion from '(lambda at test_accessor.cc:82:46)' to 'testing::Action<Accessor::Foo &()> &&' for 1st argument

googletest-src/googlemock/include/gmock/gmock-actions.h:367:3: note: candidate template ignored: requirement
      '::std::is_constructible<std::__1::function<Accessor::Foo &()>, (lambda at test_accessor.cc:82:46)>::value' was not satisfied
      [with G = (lambda at test_accessor.cc:82:46)]
  Action(G&& fun) : fun_(::std::forward<G>(fun)) {}  // NOLINT
  ^

googletest-src/googlemock/include/gmock/gmock-spec-builders.h:323:46: note: passing argument to parameter 'action' here
  OnCallSpec& WillByDefault(const Action<F>& action) {
test\u accessor.cc:83:20:错误:调用“accessor::Foo”的已删除构造函数
返回此->伪访问器.GetFoo();
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test_accessor.cc:26:9:注意:“Foo”已在此处显式标记为deleted
Foo(Foo const&)=删除;
^
test_accessor.cc:82:46:错误:在
测试_accessor.cc:82:46)“到”const Action”
ON_CALL(*this,GetFoo).WillByDefault([this](){
^~~~~~~~~~
googletest src/googlemock/include/gmock/gmock actions.h:339:7:注意:候选构造函数(隐式副本构造函数)不可行:
对于第一个参数,没有已知的从“(test_accessor.cc:82:46处的lambda)”到“const testing::Action&”的转换
集体诉讼{
^
googletest src/googlemock/include/gmock/gmock actions.h:339:7:注意:候选构造函数(隐式移动构造函数)不可行:
对于第一个参数,没有已知的从“(test_accessor.cc:82:46处的lambda)”到“testing::Action&”的转换
googletest src/googlemock/include/gmock/gmock actions.h:367:3:注意:忽略候选模板:需求
“::std::is_constructible::value”未满足要求
[使用G=(测试访问器处的lambda.cc:82:46)]
动作(G&&fun):fun_(::std::forward(fun)){}//NOLINT
^
googletest src/googlemock/include/gmock/gmock spec builders.h:323:46:注意:在此处将参数传递给参数“action”
OnCallSpec和WillByDefault(const操作和操作){
问题1
auto
类型推断条引用的规则。因此,lambda的返回类型被推断为
Foo
,而不是
Foo&
,后者随后需要一个副本。如果要从lambda返回引用,则必须使用尾部返回类型语法(通过显式设置或将返回类型设置为
Foo&
,方法是使用
auto&
强制引用类型推断,或使用保留引用的
decltype(auto)
。请参阅,在最后一个链接中,相关部分是:“如果P是引用类型,则P引用的类型用于推断。”

因此,您应该更改在调用时传递给
的lambda以返回引用类型,例如:

        ON_CALL(*this, GetFoo).WillByDefault([this]() -> Foo& {
            return this->fake_accessor_.GetFoo();
        });

        ON_CALL(*this, GetBar).WillByDefault([this]() -> Bar const& {
            return this->fake_accessor_.GetBar();
        });
如果没有此选项,则会出现以下错误:

test.cpp:83:20: error: call to deleted constructor of 'Accessor::Foo'
            return this->fake_accessor_.GetFoo();
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:26:9: note: 'Foo' has been explicitly marked deleted here
        Foo(Foo const&)            = delete;
        ^
test.cpp:82:46: error: no viable conversion from '(lambda at test.cpp:82:46)' to 'const Action<Accessor::Foo &()>'
        ON_CALL(*this, GetFoo).WillByDefault([this]() {
                                             ^~~~~~~~~~
如果没有这个变化,下面的er
test.cpp:83:20: error: call to deleted constructor of 'Accessor::Foo'
            return this->fake_accessor_.GetFoo();
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:26:9: note: 'Foo' has been explicitly marked deleted here
        Foo(Foo const&)            = delete;
        ^
test.cpp:82:46: error: no viable conversion from '(lambda at test.cpp:82:46)' to 'const Action<Accessor::Foo &()>'
        ON_CALL(*this, GetFoo).WillByDefault([this]() {
                                             ^~~~~~~~~~
  MOCK_CONST_METHOD0(GetBar, Bar const&());
test.cpp:86:46: error: no viable conversion from '(lambda at test.cpp:86:46)' to 'const Action<Accessor::Bar &()>'
        ON_CALL(*this, GetBar).WillByDefault([this]() -> Bar const& {
                                             ^~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/gmock/gmock-actions.h:357:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from '(lambda at test.cpp:86:46)' to 'const testing::Action<Accessor::Bar &()> &' for 1st argument
class Action {