HippoMocks - 模拟返回 unique_ptr 的函数

6

我目前无法成功地模拟一个返回unique_ptr的接口。例如,给定以下代码:

struct IFoo {     
    virtual std::unique_ptr<IFoo> foo = 0;
};


int main()
{
    MockRepository mocks;
    auto foo = mocks.Mock<IFoo>();
    mocks.OnCall( foo, IFoo::foo )
         .Return( std::unique_ptr<IFoo>() );
}

这个无法编译,因为Return实现会复制unique_ptr。

Call &Return(Y obj) { retVal = new ReturnValueWrapper<Y>(obj); return *this; }

期望返回unique_ptr

template <typename Z>
Z MockRepository::DoExpectation(base_mock *mock, std::pair<int, int> funcno, const base_tuple &tuple)
{
    ...
    return ((ReturnValueWrapper<Z> *)call->retVal)->rv;
}

我已经尝试了建议中的Do类似返回引用的问题)。

我还尝试编写了自己的ValueWrapper<T>,生成了一个unique_ptr,但是在某个地方值总是被复制。目前我已经没有更多想法了。


1
看起来HippoMocks还没有准备好支持C++11的移动语义类型。也许你可以为ReturnValueWrapper<std::unique_ptr<IFoo>>编写一个专门化实现,以避免内部复制? - Arne Mertz
你尝试过Hippomocks的更新版本吗?它有C++0x版本。 - Dave S
@Arne 我之前大致尝试过类似的方法,但显然一开始做错了些什么。再试一次后,我找到了一个可行的解决方案。稍后我会将其添加到 github 代码库 中。 - Thomas
@Thomas,我昨天遇到了完全相同的问题。很想在Github上看到你的更改! - Bret Kuhns
1个回答

2
问题的一个解决方案是创建一个派生接口,其中包含一个返回临时返回值的附加方法。
template <class T>
class TypedReturnValueHolder : public ReturnValueHolder {
public:
    virtual T rv() = 0;
};

并修改原始的ReturnValueHolder

template <class T>
class ReturnValueWrapper : public ReturnValueHolder {
public:
typename no_cref<T>::type rv;
ReturnValueWrapper(T rv) : rv(rv) {}
};

继承并实现派生接口。

template <class T>
class ReturnValueWrapper : public TypedReturnValueHolder<T> {
    typename no_cref<T>::type prv;
public:
    ReturnValueWrapper(T rv) : prv(rv) {}
    virtual T rv() { return prv; };
};

一旦完成了这个步骤,从DoExpectation返回的内容可以被写成:

        if (call->retVal)
            return ((TypedReturnValueHolder<Z> *)call->retVal)->rv();

当使用Do重写问题中的示例时

mocks.OnCall( foo, IFoo::foo )
     .Do( [](){ return std::unique_ptr<IFoo>(); } );

然后按预期编译并运行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接