如何使用 gmock 模拟类中的模板方法?

Bry*_*Fok 6 c++ googletest googlemock gmock

如何使用 gmock 模拟一个类的模板方法(不是模板类)?例如这样的一个类,我想模拟这个类,这个模板方法..

class A{
public:
  template<EnumType ENUM_VALUE>
  int getType(int val);
};
Run Code Online (Sandbox Code Playgroud)

我知道如何使用非虚拟方法模拟类,或模拟模板化类,但我不知道如何使用模板化方法模拟非模板化类。

Pio*_*ycz 2

  1. 第一个更好的解决方案是使用这个函数的实现A::getType- 也许它不必被嘲笑?例如:如果它只是返回构造函数中设置的一些值 - 那么只需A按照测试用例所需的方式构造即可:
class A{
public:
  A(int a) : a(a) {}
  template<typename T>
  int getType(int val)
  {
      return a + val;
  }
private:
  int a;
};

 TEST(...)
 {
      A a(TYPE_VALUE_FOR_TEST);
      ...
 }
Run Code Online (Sandbox Code Playgroud)
  1. 如果无法以这种方式完成 - 那么您可能会考虑使用一些与预处理器宏切换的 UT 工具:
 #ifdef TESTING
 namespace Testing
 {
 using std::pair<std::type_index, int> AGetTypeKey;
 std::map<AGetTypeKey, int> AGetTypeExpectedValues;
 template <typename T>
 void expectAGetType(int inputValue, int expectedResult)
 {
      AGetTypeExpectedValues[AGetTypeKey(std::type_index(typeid(T)), inputValue)] = expectedResult;
 }
 template <typename T>
 int getAGetType(int value)
 {
      return AGetTypeExpectedValues[AGetTypeKey(std::type_index(typeid(T)), inputValue)];
 }
 }
 #endif

class A{
public:
  A(int a) : a(a) {}
  template<typename T>
  int getType(int val)
  {
  #if TESTING
      return Testing::getAGetType<T>(val);
  #else
      // your "normal" implementation
      ...
  #endif
  }
private:
  int a;
};

 // compiled with -DTESTING=1
 #ifndef TESTING
 #error ...
 #endif
 TEST(...)
 {
      Testing::expectAGetType<float>(EXPECTED_INPUT_VALUE,
                                     TYPE_VALUE_FOR_FLOAT);
      ...
 }
Run Code Online (Sandbox Code Playgroud)

关于第 2 点 - 当然,所有测试代码都应该小心地与“正常代码”分开 - 例如在一些单独的头文件中。

值得一提的是,这些解决方案都不是完美的 - 并且第二个解决方案可能不是 100% 可靠,因为您测试的不是真正的代码,而是它的一些可测试版本。

也许你应该从重新思考你的设计开始——因为看起来设计并没有考虑到“可测试性设计”。