GMock - returning default value with ON_CALL for overloaded methods
@tx34 has the crux of the answer, but there are a few more issues in the code.
Firstly, the docs on Selecting Between Overloaded Functions are most appropriate. You have three overloads of fooMethod
with the same number of arguments but different argument types. You're going to have to use a matcher that specifies the type.
Next, you need to define all your Foo
functions which are to be mocked as virtual
, or else invoking them through a Foo
object won't call the derived mock functions. Since you're defining Foo
as a base class, it should also have a virtual destructor to avoid slicing.
Finally, you need to have FooMock
inherit from Foo
.
So putting it all together, you end up with something like:
#include <memory>
#include <string>
#include "gtest/gtest.h"
#include "gmock/gmock.h"
using ::testing::_;
using ::testing::An;
using ::testing::Matcher;
using ::testing::TypedEq;
using ::testing::Return;
struct Foo {
virtual ~Foo() {}
virtual int fooMethod(const int&) { return 0; }
virtual int fooMethod(const float&) { return 0; }
virtual int fooMethod(const std::string&) { return 0; }
};
struct FooMock : Foo {
FooMock() : Foo() {
ON_CALL(*this, fooMethod(An<const int&>())).
WillByDefault(Return(-1));
ON_CALL(*this, fooMethod(Matcher<const float&>(_))).
WillByDefault(Return(-2));
ON_CALL(*this, fooMethod(TypedEq<const std::string&>("1"))).
WillByDefault(Return(-3));
}
MOCK_METHOD1(fooMethod, int(const int& intParam));
MOCK_METHOD1(fooMethod, int(const float& floatParam));
MOCK_METHOD1(fooMethod, int(const std::string& stringParam));
};
TEST(Foo, foo) {
std::shared_ptr<Foo> foo(new FooMock);
auto foo_mock(std::dynamic_pointer_cast<FooMock>(foo));
EXPECT_CALL(*foo_mock, fooMethod(Matcher<const int&>(_))).Times(1);
EXPECT_CALL(*foo_mock, fooMethod(Matcher<const float&>(_))).Times(1);
EXPECT_CALL(*foo_mock, fooMethod(Matcher<const std::string&>(_))).Times(1);
EXPECT_EQ(-1, foo->fooMethod(1));
EXPECT_EQ(-2, foo->fooMethod(1.0f));
EXPECT_EQ(-3, foo->fooMethod("1"));
}
int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
The problem is TypedEq expects a value not a matcher. You can achieve what you want by:
ON_CALL(*this, fooMethod(An<ArgType>())).WillByDefault(Return(-1));
or
ON_CALL(*this, fooMethod(Matcher<ArgType>(_))).WillByDefault(Return(-1));
See also:
https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md#selecting-between-overloaded-functions-selectoverload
https://github.com/google/googletest/blob/master/docs/gmock_cheat_sheet.md#wildcard
https://github.com/google/googletest/blob/master/docs/gmock_cheat_sheet.md#generic-comparison