8

我正在尝试为包含三个重载方法的类编写模拟,即:

#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,卢卡斯

4

2 回答 2

12

@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();
}
于 2013-05-14T22:00:36.907 回答
2

问题是 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#wildcard

https://github.com/google/googletest/blob/master/docs/gmock_cheat_sheet.md#generic-comparison

于 2013-05-14T16:25:18.050 回答