gmock SetArgReferee: Set a non-copyable non-moveable object

Viewed 721

I'm using gmock and have mocked a function that takes boost::beast::http::response_parser as an out parameter. Function signature looks something like:

error_code readFromSocket(boost::beast::http::response_parser& resp);

Now, to test this function, I mocked and use EXPECT_CALL like:

boost::beast::http::response_parser respObject;
// set status code in respObject
EXPECT_CALL(mockObject, readFromSocket(_))
    .Times(1)
    .DoAll(SetArgReferee<0>(respObject), Return(err::success));

And it returns me an operator= deleted compilation error. I have tried various combinations using ByRef, ByMove, using std::ref but none of them works and I understand why they don't work.

Has anyone ever ran into a similar situation before and know how to solve this error? Please let me know if you need clarification.

Thank you.

EDIT

This is what readFromSocket looks like:

template<typename T>
error_code readFromSocket(beast::http::response_parser<T>& resp,
                          boost::asio::yield_context yield)
{
    // read from socket using beast::http::async_read
    return success;
}

This is how I call it.

beast::http::response_parser<beast::http::string_body> resp;
resp.body_limit((std::numeric_limits<std::string::size_type>::max)());
auto ec = readFromSocket(resp, yield);

// after this I do error handling and response status code handling.
1 Answers

I was trying to achieve the same behaviour and WithArg was the key. This is an example of what I ended up with:

#include <gmock/gmock.h>
#include <gtest/gtest.h>


using namespace testing;

struct NonCopyable {
    NonCopyable() = default;
    NonCopyable(const NonCopyable&) = delete;
    NonCopyable& operator=(const NonCopyable&) = delete;

    int a;
};

struct WorkWithNonCopyable {
    virtual ~WorkWithNonCopyable() = default;

    virtual bool modify_non_copyable(NonCopyable& nc) = 0;
};

struct WorkWithNonCopyableMock {
    MOCK_METHOD1(modify_non_copyable, bool(NonCopyable& nc));
};

TEST(WorkWithNonCopyableTest, NormalizedRoiDetectorTest) {
    WorkWithNonCopyableMock work_with_non_copyable_mock{};

    EXPECT_CALL(work_with_non_copyable_mock, modify_non_copyable(_))
        .WillOnce(DoAll(WithArg<0>([](auto& arg) { arg.a = 42; }), Return(true)));

    NonCopyable non_copyable;
    ASSERT_TRUE(work_with_non_copyable_mock.modify_non_copyable(non_copyable));
    ASSERT_EQ(non_copyable.a, 42);
}
Related