Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using google test to check callbacks

I have a class Foo that stores a pointer to a callback. The callback could be invoked with a method InvokeCallback().

void* SomeCallback(void* a) {

  return (void*)(*(int*)a + 10);

}


class Foo {

public: 

    typedef void* (*CallbackFunction)(void*);

    SetCallback(CallbackFunction callback) {
        this->callback = callback;
    }

    InvokeCallback() {
        callback(20);
    }

private:

    CallbackFunction callback;

}

How is it possible to test (using google test) that SomeCallback() was invoked with a specific parameter (20 in the abovementioned case)?

EDIT:

I came up with a very ugly looking solution. The tests are passed, but the new error appeared at the end ERROR: 1 leaked mock object found at program exit.

class MockCallbackClass {
public:
    MOCK_METHOD1(SomeCallback, void*(void*));
};

MockCallbackClass mock; // Nasty global variable

void* __SomeOtherCallback(void* a) {

    return mock.SomeCallback(a);

}

TEST(Callback, MockCallback) {

    Foo foo;
    foo.SetCallback(__SomeOtherCallback);
    EXPECT_CALL(mock, SomeCallback((void*)10)).WillOnce(testing::Return((void*)20));

}
like image 459
Konstantin Avatar asked Feb 16 '17 06:02

Konstantin


People also ask

What is Google mock test?

Google C++ Mocking Framework (or Google Mock for short) is a library (sometimes we also call it a “framework” to make it sound cool) for creating mock classes and using them. It does to C++ what jMock and EasyMock do to Java.

What is Expect_call GTest?

EXPECT_CALL not only defines the behavior, but also sets an expectation that the method will be called with the given arguments, for the given number of times (and in the given order when you specify the order too).

What is Googlemock?

Gmock is a mocking framework for the Groovy language. Gmock is all about simple syntax and readability of your tests so you spend less time learning the framework and more writing code. To use Gmock just drop the gmock jar file in your classpath.

What is matcher in GTest?

A matcher matches a single argument. You can use it inside ON_CALL() or EXPECT_CALL() , or use it to validate a value directly using two macros: Macro.


1 Answers

Use std::function<void*(void*)> and testing::MockFunction<void*(void*)> to mock this std::function. Of course this requires slight changes in your implementation - but functionality of your design does not change, because raw function pointers can be stored in std::function without problems:

class Foo {
public: 

    using CallbackFunction = std::function<void*(void*)>;
    // rest of this class is as it was
};

And test like this:

class FooTest : public testing::Test {
public: 

    using CallbackFunctionMock = testing::MockFunction<void*(void*)>;
    CallbackFunctionMock  callbackFunctionMock;

    Foo  objectUnderTest{[this](void* v) { return callbackFunctionMock.Call(v); }};
};
TEST_F(FooTest, shallCallbackBeCalledByInvoke)
{
    int a = 40;
    EXPECT_CALL(callbackFunctionMock, Call(reinterpret_cast<void*>(20)).WillOnce(Return((void*)(&a));
    objectUnderTest.InvokeCallback();
}
like image 112
PiotrNycz Avatar answered Oct 11 '22 10:10

PiotrNycz