Я пытаюсь написать макет для класса, который содержит три перегруженных метода, т.е.
#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 FAQ, Wiki и не нашел решения — как я могу вернуть значение по умолчанию с ON_CALL для перегруженных методов?
BR,
Лукаш
У @ tx34 есть суть ответа, но в коде есть еще несколько проблем.
Во-первых, документы по Выбор между перегруженными функциями являются наиболее подходящими. У вас есть три перегрузки fooMethod
с одинаковым количеством аргументов, но с разными типами аргументов. Вам нужно будет использовать средство сопоставления, которое определяет тип.
Далее вам нужно определить все ваши Foo
функции, которые должны быть смоделированы как virtual
или же вызывать их через Foo
объект не будет вызывать производные фиктивные функции. Так как вы определяете Foo
как базовый класс, он также должен иметь виртуальный деструктор, чтобы избежать нарезки.
Наконец, вам нужно иметь FooMock
наследовать от Foo
,
Итак, собрав все это, вы получите что-то вроде:
#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/googlemock/docs/CheatSheet.md#wildcard
https://github.com/google/googletest/blob/master/googlemock/docs/CheatSheet.md#generic-comparison