2011-09-30 60 views
37

我有一个工厂,返回一个智能指针。无论使用什么智能指针,我都无法让Google Mock嘲笑工厂方法。Google可以用智能指针返回类型来模拟一个方法吗?

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

MOCK_METHOD0(Create, std::unique_ptr<IMyObjectThing>()); 

我也得到:

"...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>'" 

类型指出,在智能指针定义。

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

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

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

回答

-1

在大多数情况下,Google Mock要求模拟方法的参数和返回值是可复制的。每boost's documentation,unique_ptr不可复制。您可以选择返回一个使用共享所有权的智能指针类(shared_ptr,linked_ptr等)并因此可复制。或者你可以使用一个原始指针。由于所讨论的方法显然是构造一个对象的方法,所以我没有看到返回一个原始指针的固有问题。只要您将结果分配给每个呼叫站点的某个共享指针,您都会很好。

+31

你不需要对你的类的接口做任何改变,只是为了让它们与你的模拟框架一起工作。通常这是不可能的。这对我来说不是一个可接受的解决方案! –

+12

工厂类返回一个原始指针对我来说似乎是不可接受的。在这种情况下,unique_ptr最有意义。它的设计部分是为了解决“将结果分配给*每个*呼叫站点上的某个共享指针”的问题。 –

+3

我不认为这是正确的答案,将所有内容都改为原始或共享所有权并不是一种解决方案,只是为了测试事情! – paulm

78

谷歌模拟框架的非(可复制)函数参数和retun值问题的一个可行的解决方法是使用代理模拟方法。

假设你有下面的接口定义(如果它是良好的作风以这种方式使用std::unique_ptr似乎或多或少的一个哲学问题,我个人比较喜欢它强制过户):

class IFooInterface { 
public: 
    virtual void nonCopyableParam(std::unique_ptr<IMyObjectThing> uPtr) = 0; 
    virtual std::unique_ptr<IMyObjectThing> nonCopyableReturn() = 0; 
    virtual ~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*()); 
}; 

你只需要照顾,即配置(所采取的行动)的nonCopyableReturnProxy()方法在回报NULL或instanc在堆上动态分配。


有一个google-mock user forum thread讨论这个话题,其中的维护者之一指出,谷歌,模拟框架不会改变,以支持该今后他们认为他们的政策极力劝阻使用std::auto_ptr参数。如前所述,这是恕我直言的哲学观点,而模拟框架的功能不应该引导您想要设计什么样的接口,或者您可以使用第三方API。

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

+0

您链接到主要关于'auto_ptr'按值的讨论中的线程是一个糟糕的计划(和哦,哇,就像'auto_ptr'周围的大部分事情一样):但上面的问题是关于'unique_ptr',否? – Yakk

+0

@Yakk这是因为我在我的实际测试用例中使用了'std :: auto_ptr',但同样的原理也适用于'std :: unique_ptr'。你怎么看,我是否应该相应地编辑问题? –

+0

只是这一点:“这种使用智能指针参数” - 强烈的沮丧是关于'auto_ptr'参数,在'unique_ptr'存在之前于2010年编写。修改框架以使'auto_ptr'能够被滥用是一个相当可接受的位置:在'unique_ptr'出现之后这样做是不同的一堆鱼。如果你检查他们将'auto_ptr'作为一个合理的参数类型的原因,它们不适用于'unique_ptr'。 – Yakk

相关问题