Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Google Mock with boost::bind

I have a class whose constructor takes a Boost function, and I'd like to test it with Google Mock. The following code shows a sample class and my attempt to test it:

MyClass.h:

#include <boost/function.hpp>
class MyClass
{
public:
    MyClass(boost::function<void()> callback);
    void callCallback();
private:
    boost::function<void()> m_callback;
};

MyClassTest.cpp:

#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <boost/bind.hpp>
#include "MyClass.h"
class CallbackMock
{
public:
    MOCK_METHOD0(callback, void());
};

TEST(MyClassShould, CallItsCallback)
{
    CallbackMock callbackMock;
    MyClass myClass(boost::bind(&CallbackMock::callback, callbackMock));
    EXPECT_CALL(callbackMock, callback()).Times(1);
    myClass.callCallback();
}

Attempting to compile MyClassTest.cpp in Visual Studio 2008 gives the following error:

...gmock/gmock-generated-function-mockers.h(76) : error C2248: 'testing::internal::FunctionMockerBase::FunctionMockerBase' : cannot access private member declared in class 'testing::internal::FunctionMockerBase' 1> with 1> [ 1>
F=void (void) 1> ] 1>
.../gmock-spec-builders.h(1656) : see declaration of 'testing::internal::FunctionMockerBase::FunctionMockerBase' 1> with 1> [ 1>
F=void (void) 1> ] 1>
This diagnostic occurred in the compiler generated function 'testing::internal::FunctionMocker::FunctionMocker(const testing::internal::FunctionMocker &)' 1> with 1> [ 1>
Function=void (void) 1> ]

The error stems from the line containing boost::bind. Replacing the mocked method with void callback(){} eliminates the compile error (but also eliminates the use of Google Mock, defeating the purpose). Is what I'm trying to do possible without modifying the tested class?

like image 519
Dave Taflin Avatar asked Apr 07 '11 16:04

Dave Taflin


2 Answers

The reason is that Google Mock mocks are not copyable - that is by design. When you try to pass it into boost::bind by value, the compiler fails to generate the copy constructor. You should take the mock's address when passing it into bind:

MyClass myClass(boost::bind(&CallbackMock::callback, &callbackMock));
like image 95
VladLosev Avatar answered Sep 28 '22 10:09

VladLosev


I think this line is wrong:

MyClass myClass(boost::bind(&CallbackMock::callback, callbackMock));

The last parameter should be &callbackMock

like image 35
Ben Avatar answered Sep 28 '22 12:09

Ben