c++mockingsmart-pointersunique-ptrtrompeloeil

How to handle return of unique_ptr in trompeloeil RETURN expectations


Hope this message finds you well.

I'm a little bit lost while using trompeloeil expectations syntax. Let's say I have this:

#include <memory>

class IA {
public:
    virtual ~IA() = default;
    virtual void print() = 0;
}

class A : public IA {
public:
    A(int p_i) : _i{ p_i }
    {}
    virtual ~A() = default;
    void print() override;
private:
    int _i;
};

class IB {
    virtual std::unique_ptr<IA> buildA() const = 0;
};

class B : public IB {
public:    
    std::unique_ptr<IA> buildA() const override {
        return std::move( std::make_unique<A>(42) );
    }
};

class MockB : public trompeloeil::mock_interface<IB> {
    IMPLEMENT_CONST_MOCK0( buildA );
};

class C {
public:
    C(std::unique_ptr<IB> p_b) : _b{ std::move( p_b ) }
    {}

    void doStuff() const {
        auto A = p_b->buildA();
        // Do stuff with A
        // ...
    }

private:
    std::unique_ptr<IB> _b;
};

int main()
{
    auto mock = std::make_unique<MockB>();
    // Keep the pointer of the mock to use it later in the test
    auto ptr_mock = mock.get();

    C c{ std::move(mock) };
    
    REQUIRED_CALL( *ptr_mock, buildA() )
        .RETURN( ?????? );

    c.doStuff();

    return 0;
}

How can I return the std::unique_ptr in the RETURN from trompeloeil ?

From my understanding, RETURN only works by value and reference... as seen here

unique_ptr are not copiable and I tend to have an error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) because of this.


Solution

  • you can return a new unique_ptr every time.

    REQUIRE_CALL(*ptr_mock, buildA())
        .RETURN(std::make_unique<A>(1));
    

    online demo

    or you can move out of a stack variable.

    auto ptr_a = std::make_unique<A>(1);
    
    REQUIRE_CALL(*ptr_mock, buildA())
        .LR_RETURN(std::move(ptr_a));
    

    online demo