Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I mock a method with a return type of unique_ptr in Google Mock?

I have read Can Google Mock a method with a smart pointer return type? but it did not really give much of an answer.

I have a factory that returns unique_ptr instances. Returning unique_ptr is a requirement that cannot change without really good reason and a discussion with those above my pay grade (which I am willing to do if it plain turns out you should not be returning these things).

In the code being tested, there are three objects in question. The first is a handler of sorts. Using that handler, you can create the second object, which is the only real interesting one after everything is said and done. But creating that second one is a complex process that requires extra work done by the specific handler instance, as well as a factory (the third object) to take care of logic needed in creating Mr. Second regardless of handler requirements.

Here's the testing code in question (with class names changed in order to avoid HR hell):

class BarTest : public ::testing::Test
{
protected:
    Bar foo;
};

TEST_F(BarTest, createFoo)
{
    // Data used in this test
    std::string fooName = "test";
    MockFooFactory<int> fooFactory;

    MockFoo<int>* foo = new MockFoo<int>;

    // When createFoo is called, it should call the foo factory's construct method with the given
    // fooName and a pointer to the calling bar
    EXPECT_CALL(fooFactory, construct(fooName, &bar)).
        WillOnce(::testing::Return(std::unique_ptr<Foo<int>>(foo)));

    // Test it
    std::unique_ptr<Foo<int>> returnedFoo = bar.createFoo(fooName, fooFactory);

    // createFoo should return the foo returned by the factory's construct method
    ASSERT_EQ(foo, returnedFoo.get());
}

As one might expect, upon compiling this (specifically with GCC) the compiler complains about using the deleted copy constructor. I do not think there is a way to finagle this around in order to impose move semantics (at the very least not through the admittedly naive approaches I tried), and just telling it to return the raw pointer and hoping it can wrap it up itself also failed (potentially naive as well), so I am stuck.

At this point I am really leaning towards making a fake, but I would like to give it one last shot with pure mocking. If there is some way I can get this return to work, that would be fantastic. Either way, I have full control over the mocking and testing, so as long as this case gets covered (hopefully without hackiness) how direct or indirect the approach is not a concern.

like image 865
dawsonc623 Avatar asked Jul 31 '15 10:07

dawsonc623


People also ask

What is difference between On_call and Expect_call?

So use ON_CALL by default, and only use EXPECT_CALL when you actually intend to verify that the call is made.

What is the difference between Gmock and Gtest?

In real system, these counterparts belong to the system itself. In the unit tests they are replaced with mocks. Gtest is a framework for unit testing. Gmock is a framework imitating the rest of your system during unit tests.

How do you make a mock Gmock?

Using the Turtle interface as example, here are the simple steps you need to follow: Derive a class MockTurtle from Turtle . Take a virtual function of Turtle (while it's possible to mock non-virtual methods using templates, it's much more involved). In the public: section of the child class, write MOCK_METHOD();

How do you mock a function in Gmock?

It is not possible to directly mock a free function (i.e. a C-style function or a static method). If you need to, you can rewrite your code to use an interface (abstract class).


1 Answers

I know this post is very old and you've probably discovered the answer by now.

However, a new piece of information is that in April 2017, gmock introduced a new Action modifier "ByMove".

EXPECT_CALL(*foo_, Bar(_, )).WillOnce(Return(ByMove(some_move_only_object)));
like image 188
jeff Avatar answered Oct 01 '22 14:10

jeff