可以谷歌模拟一个方法与智能指针返回类型



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

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

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时,错误提示没有复制构造函数,这让我很困惑。

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

我的环境是Visual Studio 2010 Ultimate和Windows 7。

对于google mock框架的非(const)可复制函数参数和返回值问题,一个可行的解决方案是使用代理模拟方法。

假设您有以下接口定义(如果以这种方式使用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或在堆上动态分配的实例。


有一个google-mock用户论坛讨论了这个主题,其中一个维护者声明google-mock框架在将来不会被修改来支持这个主题,因为他们的策略强烈反对使用std::auto_ptr参数。如上所述,这是我个人的哲学观点,mock框架的功能不应该引导你想要设计的接口类型或你可以从第三方api中使用的接口类型。

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

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

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

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

some_move_only_object可以是一个std::unique_ptr.

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

在模拟类中放置与您想要的相同的

MOCK_METHOD0(创建、std:: unique_ptr ());


,在测试中如下

EXPECT_CALL(<mock-obj>, Create())
.WillOnce([]()->std::unique_ptr<IMyObjectThing>{
    return std::make_unique<IMyObjectThing>();
});

如果vs 2010不支持lambda,可以使用函子

我最近发现通过模拟函数返回智能指针仍然不是很用户友好。是的,新的动作ByMove已经被引入,但事实证明,它可能只在测试中使用一次。假设您有一个要测试的工厂类,它会反复将unique_ptr返回给新创建的对象。

任何对.WillRepeatedly(Return(ByMove)或多个ON_CALL使用.WillByDefault(Return(ByMove)的尝试将导致以下错误:

[FATAL] Condition ! performanmed_ failed。ByMove()操作应该只执行一次。

这在GMock Cookbook的段落"mock Methods That Use Move-Only Types"中也有明确的说明。

Google Mock要求被模拟方法的参数和返回值在大多数情况下是可复制的。根据boost的文档,unique_ptr是不可复制的。您可以选择返回一个使用共享所有权的智能指针类(shared_ptr, linked_ptr等),因此是可复制的。或者您可以使用原始指针。由于所讨论的方法显然是构造对象的方法,因此我认为返回原始指针没有固有的问题。只要在每个调用点将结果赋值给某个共享指针,就不会有问题。

相关内容

  • 没有找到相关文章

最新更新