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

时间:2017-05-11 09:57:42

标签: c++ googletest googlemock gmock

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

class A{
public:
  template<EnumType ENUM_VALUE>
  int getType(int val);
};

我知道如何用非虚方法模拟一个类,或模拟一个模板化的类,但我不知道如何用模板化方法模拟一个非模板化的类..

2 个答案:

答案 0 :(得分:2)

  1. 第一个更好的解决方案是使用此函数A::getType的实现 - 也许它不必被嘲笑?例如:如果它只是返回一些在构造函数中设置的值 - 那么只需按照测试用例中需要的方式构造A
  2. 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);
          ...
     }
    
    1. 如果无法以这种方式完成 - 那么您可能会考虑使用预处理器宏切换UT的一些工具:
    2.  #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);
            ...
       }
      

      关于第2点 - 当然所有测试代码都应该与&#34;普通代码&#34; - 例如在一些单独的头文件中。

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

      也许你应该从重新思考你的设计开始 - 因为似乎设计没有用&#34; design for testability&#34;记住。

答案 1 :(得分:0)

我最终做了一个继电器来模拟方法

E.g。

&#13;
&#13;
class MOCK_A{
public:
  template<Enum ENUM_VALUE>
  int getType(int val){
    getType(val, ENUM_VALUE);
  }
  
  MOCK_METHOD1(getType, int(int val, Enum enum_value));
};
&#13;
&#13;
&#13;