How to use gmock to mock up a std::function?
Asked Answered
V

2

10

The constructor of my class is

A( ...
   std::function<bool(const std::string&, const std::string&)> aCallBack, 
   ... );

I want to use EXPECT_CALL to test it. This callback is from another class B. I created a Mock like

class BMock : public B
{
    MOCK_METHOD2( aCallBack, bool(const std::string&, const std::string&) );
}

Then I tried

B *b = new B();
std::function<bool(const std::string&, const std::string&)> func = 
    std::bind(&B::aCallBack, b, std::PlaceHolders::_1, std::PlaceHolders::_2);

It still does not work. How can I get a function pointer of a gmock object?

Thanks!!

Vickyvico answered 1/3, 2017 at 0:18 Comment(0)
C
33

If you want to use mock to keep track of calls and set return values, you can use MockFunction.

using testing::_;
using testing::MockFunction;
using testing::Return;

MockFunction<bool(const std::string&, const std::string&)> mockCallback;

EXPECT_CALL(mockCallback, Call(_, _)).WillOnce(Return(false)); // Or anything else you want to do

A( ...
   mockCallback.AsStdFunction()
   ...);

Consanguineous answered 28/8, 2019 at 11:20 Comment(4)
This is golden. Been looking for this across multiple related stack overflow posts, and your answer was the first I found that mentioned MockFunction and provided a complete example.Six
I am not sure why this was never mentioned in the documentation. Am I missing something?Cockspur
It's documented in Cookbook at least - github.com/google/googletest/blob/master/googlemock/docs/…Consanguineous
Unfortunately, all MockFunctions are identified as Call in error messages which is very unhelpful...Chan
D
-3

With unit testing you should only test your class A so your test should just check if any function passed to the constructor gets called. So you don't need a mock, instead just pass a lambda that just record with a boolean (or a counter).

bool gotCalled = false;
A a( [&gotCalled]( const std::string&, const std::string& ) { gotCalled = true; return true; } );
...
ASSERT_TRUE( gotCalled );
Delegate answered 2/3, 2017 at 10:51 Comment(2)
Anyway, although it's fine passing a function to the constructor, architecturally it doesn't smell right if it's used as callback. Generally it would be better to pass it to the function that actually is using it.Delegate
this answer has nothing to do with an actual solution to TS problem, for the actual answer please check Enzam's answerKurtz

© 2022 - 2024 — McMap. All rights reserved.