2013-03-01 44 views
6

我目前没有成功模拟一个返回unique_ptr的接口。例如,给定HippoMocks - 模拟一个函数,返回一个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,建议for a similar problem with returned references

我也试过编写我自己的ValueWrapper<T>,它生成一个unique_ptr,但在某处值总是被复制。现在我已经没有想法了。

+1

看来HippoMocks还没有准备好用于C++ 11的移动类型。也许你可以为'ReturnValueWrapper >'编写一个专门化程序,它不会*在内部复制? – 2013-03-01 14:58:20

+0

你有没有试过hippomocks以后的版本,有一个C++ 0x版本? – 2013-03-01 16:00:43

+0

@Arne我或多或少地尝试过这样的事情。显然我最初做错了什么。在另一个去之后,我发现了一个可行的解决方案。稍后我会将它添加到[github存储库](https://github.com/dascandy/hippomocks)。 – Thomas 2013-03-01 17:15:26

回答

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回报可以从问题重写时使用Do

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

然后编译和运行的写作

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

的例子预期。