1

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.

3
  • Have you tried asking the authors of this library (trompeloeil) ? (e.g. by an issue in git) Commented Jul 6 at 7:43
  • That's actually what I should have done on the first place...I just assumed that another person must have already faced this issue... Thanks for the advice. Will do it. Commented Jul 6 at 7:49
  • 2
    std::unique_ptr<IA> buildA() const override { return std::move( std::make_unique<A>(42) ); } On harmful overuse of std::move More on harmful overuse of std::move Commented Jul 6 at 8:25

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for your answer. Could you elaborate more on this please ? Why would it work ? How does the RETURN doesn't copy the unique_tr you just created ? I'm sorry if I'm lost
at least right now, the content of RETURN(...) is wrapped into a lambda that it invoked every time, so whatever you put in there will get invoked every time.
Oh! I didn't know that the content of the macro RETURN was a lambda...I have to check the source code then. Could i ask you the opposition question please ? Why then, my way of doing is not correct for the lambda ? Thank you so much for pointing me in the right direction.
i added a way to move out of a stack variable.
lambdas cannot capture non-copyable objects by value
"lambdas cannot capture non-copyable objects by value" You can init capture move-only types, which is a capture by value (ex. auto f = [x = std::move(x)] ...)
that won't work with that library because it doesn't give you access to the captures field.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.