I'm trying to write mock for a class which contains three overloaded methods, ie.:
#include <gtest/gtest.h>
#include <gmock/gmock.h>
using ::testing::_;
using ::testing::Return;
using ::testing::A;
using ::testing::ByRef;
using ::testing::Ref;
using ::testing::TypedEq;
struct Foo {
int fooMethod(const int& intParam) { return 0; }
int fooMethod(const float& floatParam) { return 0; }
int fooMethod(const std::string& stringParam) { return 0; }
};
struct FooMock {
FooMock() {
ON_CALL(*this, fooMethod(_)).WillByDefault(Return(-1));
}
MOCK_METHOD1(fooMethod, int(const int& intParam));
MOCK_METHOD1(fooMethod, int(const float& floatParam));
MOCK_METHOD1(fooMethod, int(const std::string& stringParam));
};
but this gives an error:
error: call of overloaded ‘gmock_fooMethod(const testing::internal::AnythingMatcher&)’ is ambiguous
I've also tried TypedEq() instead of "_", but it gives more obscure errors. I've checked GMock FAQ, Wiki and I didn't find solution - how can I return default value with ON_CALL for overloaded methods?
BR, Lukasz
@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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With