gmock pointer to base class has no member gmock_
Asked Answered
L

1

5

Sorry if the title isn't clear.

I have a virtual base class:

class FileSystemInterface {
public:
    virtual ~FileSystemInterface() {};

    virtual void save(std::string file_content) = 0;
};

My mock class derives from this:

class MockFile : public FileSystemInterface
{
public:
    MOCK_METHOD1(save, void(std::string));
};

Now I have a method I'm testing that takes a unique pointer to FileSystemInterface:

void my_method(std::unique_ptr<FileSystemInterface>& interface)

My test code is as follows:

std::unique_ptr<FileSystemInterface> mockFile(new MockFile);
EXPECT_CALL(*mockFile, save(_));
my_method(mockFile);

The problem is that EXPECT_CALL gives me an error class "FileSystemInterface" has no member "gmock_save"

Presumably that is because my mock is a pointer to the base class, but if I change my test as follows:

std::unique_ptr<MockFile> mockFile(new MockFile);
EXPECT_CALL(*mockFile, save(_));
my_method(mockFile);

Then EXPECT_CALL is fine but now my_method complains: a reference of type "std::unique_ptr<FileSystemInterface, std::default_delete<FileSystemInterface>> &" (not const-qualified) cannot be initialized with a value of type "std::unique_ptr<MockFile, std::default_delete<MockFile>>"

How can I get around this conflict and create my test? Thank you.

UPDATE

As is pointed out in Alexey Guseynov answer, my method does take ownership of the pointer, so the thing to do was change my method to

void my_method(std::unique_ptr<FileSystemInterface> interface);

and run my test like this:

std::unique_ptr<MockFile> mockFile(new MockFile);
EXPECT_CALL(*mockFile, save(_));
my_method(std::move(mockFile));
Latton answered 17/5, 2017 at 15:21 Comment(1)
My guess would be to use std::unique_ptr<MockFile> mockFile(new MockFile);. But then again, I have no experience with mocks in C++...Threedimensional
T
9

You must store the mock as MockFile, like this:

std::unique_ptr<MockFile> mockFile(new MockFile);  // not so obvious change
EXPECT_CALL(*mockFile, save(_));
my_method(mockFile);

But you need to change signature of your method. It is strange to take a reference to unique_ptr because it is not clear who owns the object. If my_method owns the mockFile, then transfer the ownership by moving the pointer in-to the method (pass it by value). If my_method does not own the file, then pass it as a plain pointer.

Trichromatic answered 17/5, 2017 at 15:27 Comment(1)
The not obvious thing @Alexey Guseynov's corrects in @dseiple's code is in his first line of code sample: use std::unique_ptr<MockFile> ...instead of std::unique_ptr<FileSystemInterface> ...Racy

© 2022 - 2024 — McMap. All rights reserved.