我正试图为一个包含三个重载方法的类编写mock,即:
#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));
};
,但这给出了一个错误:
error: call of overloaded ‘gmock_fooMethod(const testing::internal::AnythingMatcher&)’ is ambiguous
我也尝试过TypedEq()而不是"_",但它给出了更多模糊的错误。我已经检查了GMock常见问题解答,维基和我没有找到解决方案-我怎么能返回默认值与ON_CALL重载方法?
BR,卢卡斯
@tx34找到了关键的答案,但是代码中还有一些问题。
首先,在重载函数之间进行选择的文档是最合适的。你有三个重载的fooMethod
有相同数量的参数,但是不同的参数类型。你必须使用匹配器来指定类型。
接下来,您需要定义所有将被模拟为virtual
的Foo
函数,否则通过Foo
对象调用它们将不会调用派生的模拟函数。由于您将Foo
定义为基类,因此它还应该具有虚析构函数以避免切片。
最后,需要从Foo
继承FooMock
。
所以把它们放在一起,你最终会得到这样的东西:
#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();
}
问题是TypedEq期望一个值而不是一个匹配器。你可以实现你想要的:
ON_CALL(*this, fooMethod(An<ArgType>())).WillByDefault(Return(-1));
或
ON_CALL(*this, fooMethod(Matcher<ArgType>(_))).WillByDefault(Return(-1));
参见:
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通配符
https://github.com/google/googletest/blob/master/docs/gmock_cheat_sheet.md generic-comparison