Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.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++_Unit Testing_Smart Pointers_Googlemock - Fatal编程技术网

C++ Google可以模拟具有智能指针返回类型的方法吗?

C++ Google可以模拟具有智能指针返回类型的方法吗?,c++,unit-testing,smart-pointers,googlemock,C++,Unit Testing,Smart Pointers,Googlemock,我有一个返回智能指针的工厂。无论我使用什么样的智能指针,我都无法让Google Mock模拟工厂方法 模拟对象是纯抽象接口的实现,其中所有方法都是虚拟的。我有一个原型: MOCK_METHOD0(Create, std::unique_ptr<IMyObjectThing>()); MOCK_METHOD0(创建,std::unique_ptr()); 我得到: "...gmock/gmock-spec-builders.h(1314): error C2248: 'std::u

我有一个返回智能指针的工厂。无论我使用什么样的智能指针,我都无法让Google Mock模拟工厂方法

模拟对象是纯抽象接口的实现,其中所有方法都是虚拟的。我有一个原型:

MOCK_METHOD0(Create, std::unique_ptr<IMyObjectThing>());
MOCK_METHOD0(创建,std::unique_ptr());
我得到:

"...gmock/gmock-spec-builders.h(1314): error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'"
“…gmock/gmock spec builders.h(1314):错误C2248:'std::unique_ptr::unique_ptr':无法访问类'std::unique_ptr'中声明的私有成员”
已定义智能指针中指向的类型

我知道它试图访问一个声明为私有的构造函数,但我不明白为什么。当这是一个std::auto_ptr时,错误表明没有复制构造函数,这让我很困惑

无论如何,有没有办法模拟返回智能指针的方法?还是有更好的方法来建造工厂?我唯一的决定是返回一个原始指针(blech


我的环境是Visual Studio 2010 Ultimate和Windows 7。我没有使用CLI。

谷歌模拟要求模拟方法的参数和返回值在大多数情况下是可复制的。根据,唯一的ptr不可复制。您可以选择返回一个智能指针类,该类使用共享所有权(、linked_ptr等),因此是可复制的。也可以使用原始指针。由于所讨论的方法显然是构造对象的方法,因此我认为返回原始指针没有固有的问题。只要将结果分配给每个调用站点上的某个共享指针,就不会有问题。

针对google mock framework在不可复制函数参数和retun值方面的问题,一个可行的解决方法是使用代理模拟方法

假设您有以下接口定义(如果以这种方式使用
std::unique\u ptr
是一种很好的风格,这或多或少是一个哲学问题,我个人喜欢强制所有权转移):

类ifoo接口{
公众:
虚拟void nonCopyableParam(std::unique_ptr uPtr)=0;
虚拟std::unique_ptr nonCopyableReturn()=0;
虚拟~IFooInterface(){}
};
可以这样定义适当的模拟类:

class FooInterfaceMock
: public IFooInterface {
public:
    FooInterfaceMock() {}
    virtual ~FooInterfaceMock() {}

    virtual void nonCopyableParam(std::unique_ptr<IMyObjectThing> uPtr) {
        nonCopyableParamProxy(uPtr.get());
    }
    virtual std::unique_ptr<IMyObjectThing> nonCopyableReturn() {
        return std::unique_ptr<IMyObjectThing>(nonCopyableReturnProxy());
    }


    MOCK_METHOD1(nonCopyableParamProxy,void (IMyObjectThing*));
    MOCK_METHOD0(nonCopyableReturnProxy,IMyObjectThing* ());
};
类FooInterfaceMock
:公共IFooInterface{
公众:
FooInterfaceMock(){}
虚拟~FooInterfaceMock(){}
虚拟void nonCopyableParam(std::unique_ptr uPtr){
nonCopyableParamProxy(uPtr.get());
}
虚拟std::unique_ptr nonCopyableReturn(){
return std::unique_ptr(nonCopyableReturnProxy());
}
MOCK_方法1(nonCopyableParamProxy,void(IMyObjectThing*));
MOCK_方法0(nonCopyableReturnProxy,IMyObjectThing*());
};
您只需要注意,
nonCopyableReturnProxy()
方法的配置(采取的操作)返回
NULL
或在堆上动态分配的实例


有一次讨论这个话题时,其中一位维护人员表示,google mock框架在未来将不会改变以支持此功能,他们认为他们的策略强烈反对使用
std::auto_ptr
参数。如前所述,这是IMHO的哲学观点,模拟框架的功能不应该指导您想要设计或可以从第三方API使用什么样的接口


如前所述,答案描述了一个可行的解决方法。

我知道这篇文章是很久以前写的,所以你现在可能已经找到了答案

gmock以前不支持返回任何可移动类型(包括智能指针)的模拟函数。然而,在2017年4月,gmock引入了一个新的动作修改器
ByMove

EXPECT_CALL(*foo_,Bar(_,).WillOnce(Return(ByMove(some_move_only_object)))

其中一些仅移动的对象可以是例如
std::unique\u ptr.


是的,现在gmock可以模拟一个接受智能指针的函数。

在模拟类中,按照您的需要放置相同的指针

MOCK_METHOD0(Create,std::unique_ptr())


并且在测试中如下所示

EXPECT_CALL(<mock-obj>, Create())
.WillOnce([]()->std::unique_ptr<IMyObjectThing>{
    return std::make_unique<IMyObjectThing>();
});
EXPECT\u调用(,Create())
.WillOnce([]()->std::unique_ptr{
返回std::make_unique();
});

如果vs 2010不支持lambda,您可以使用functor

我最近发现,通过模拟函数返回智能指针仍然不太方便用户。是的,已经引入了新的action
ByMove
,但是在测试过程中它只能使用一次。因此,假设您有一个要测试的工厂类,该类反复向新创建的对象返回
unique\u ptr

任何尝试
.WillByDefault(Return(ByMove)
或多次
调用
.WillByDefault(Return(ByMove)
将导致以下错误:

[致命]条件!已执行\失败。ByMove()操作只能执行一次


“使用仅移动类型的模拟方法”一段中也明确说明了这一点.

您不需要对类的接口进行任何更改,就可以让它们与您的模拟框架一起工作。通常这根本不可能。这对我来说不是一个可接受的解决方案!对于工厂类来说,返回原始指针似乎是不可接受的。在这种情况下,唯一的\u ptr最有意义。它是designned在一定程度上解决了“将结果分配给每个调用站点上的某个共享指针”的问题我不认为这是正确的答案,将所有内容更改为原始或共享所有权并不仅仅是为了进行测试!现在这是可能的,请看您链接到的主要讨论
auto_ptr
的线程(按值)是一个糟糕的计划(哦,哇,是这样吗,就像围绕
auto_ptr
的大多数事情一样):但上面的问题是关于
unique\u ptr
,不是吗?@Yakk这是因为我在实际工作中一直在使用
std::auto\u ptr
EXPECT_CALL(<mock-obj>, Create())
.WillOnce([]()->std::unique_ptr<IMyObjectThing>{
    return std::make_unique<IMyObjectThing>();
});