How can I mock object that is stored as a unique_ptr in gmock?
Asked Answered
E

1

5

I inject a dependency in some class. This class stores the dependency with an std::unique_ptr and is therefore the only owner of the object.

What is the right way to mock a method in this dependency? My current solution is to get a raw pointer from the unique_ptr before I hand over ownership. While this works, I think there are better ways to do it. What are they?

class Dependency
{
public:
    virtual int plusOne(int x) {return x+1;}
};

class Dependency_Mock : public Dependency
{
public:
    MOCK_METHOD1(plusOne, int(int));
};

class SomeClass
{
public:
    void inject(std::unique_ptr<Dependency> dep) {dependency = std::move(dep);}
    int execute(int x) {return dependency->plusOne(x);}
private:
    std::unique_ptr<Dependency> dependency;
};


TEST(SomeClassTest, executeTestWithMock)
{
    SomeClass some;
    auto dep = std::make_unique<Dependency_Mock>();
    auto& dep_ref = *(dep.get()); // This is kind of ugly.
    some.inject(std::move(dep));

    EXPECT_CALL( dep_ref , plusOne(_))
            .WillOnce(Return(5));

    EXPECT_EQ(some.execute(5), 5); // execute
}
Exasperation answered 24/12, 2017 at 1:18 Comment(0)
P
10

*(dep.get()) can be replaced directly by *dep.

Then, you can call expect before to move it:

auto dep = std::make_unique<Dependency_Mock>();
EXPECT_CALL(*dep, plusOne(_)).WillOnce(Return(5));
SomeClass some;
some.inject(std::move(dep));

EXPECT_EQ(some.execute(5), 5); // execute
Prospective answered 24/12, 2017 at 1:29 Comment(2)
Oh i see. I thought that what ever goes into the EXPECT_CALL must stay valid until the call happens.Exasperation
Does this work with Times()? ie: EXPECT_CALL(*dep, plusOne(_)).Times(1) Seems like google mock understands if it's called or not called, but not the actual number of times it's called... I know this is an old thread. Sorry for the resurrection.Nitrobenzene

© 2022 - 2024 — McMap. All rights reserved.