2013-03-01 18 views
6

Attualmente non sto riuscendo a simulare un'interfaccia che restituisce un unique_ptr. Ad esempio, datoHippoMocks - mocking di una funzione che restituisce un 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>()); 
} 

Questo non riesce a compilare perché l'implementazione Return fa una copia del unique_ptr

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

e l'aspettativa tenta di restituire l'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; 
} 

ho provato Do, come suggerito for a similar problem with returned references.

Ho anche provato a scrivere il mio ValueWrapper<T> che genera un unique_ptr, ma da qualche parte il valore ottiene sempre copiati. In questo momento sono a corto di idee.

+1

Sembra che HippoMocks non sia ancora pronto per i tipi di spostamento solo di C++ 11. Forse potresti scrivere una specializzazione per 'ReturnValueWrapper >' che * non * copia internamente? –

+0

Hai provato le versioni successive di hippomocks, che hanno una versione C++ 0x? –

+0

@Arne Ho provato più o meno qualcosa del genere. A quanto pare all'inizio ho fatto qualcosa di sbagliato. Dopo aver dato un altro tentativo ho trovato una soluzione che funzionava. Lo aggiungerò al [repository github] (https://github.com/dascandy/hippomocks) in seguito. – Thomas

risposta

2

Una soluzione al problema è quello di creare un'interfaccia derivata con un metodo aggiuntivo che restituisce il valore restituito come un temporaneo

template <class T> 
class TypedReturnValueHolder : public ReturnValueHolder { 
public: 
    virtual T rv() = 0; 
}; 

e modificare l'originale ReturnValueHolder

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

ereditare da e implementare l'interfaccia derivata.

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; }; 
}; 

Una volta che è stato fatto, il ritorno da DoExpectation può essere scritta come

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

L'esempio dalla domanda quando riscritto per utilizzare Do

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

quindi compila e viene eseguito come previsto.

Problemi correlati