How do I use gmock to mock a template method from a class?

How do I use gmock to mock a template method (not a template class) for a class? An example of such a class, I want to mock this class and this template method.

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

Run codeHide result


I know how to mock a class with non-virtual methods, or mock a template, but I don't know how to mock a template without templates with a templated method.

+3


source to share


2 answers


  • The first much better solution is to use an implementation of this function A::getType

    - maybe it shouldn't be mocked? For example: if it just returns some value that is given in the constructor, then just construct A

    as needed in your test case:
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. If this is not possible, then you may want to consider using some UT tools that switch using preprocessor macros:
 #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);
      ...
 }

      



Regarding point 2 - of course, all test code must be carefully separated from "normal code" - for example, in some split header files.

It is worth saying that none of these solutions are perfect - and this second solution may not be 100% reliable, since you will not be testing the real code, but some verifiable version.

Perhaps you should start by rethinking your design as the design was not completed with design for testability "./p>

+2


source


I end up doing relays to make fun of the method

eg.



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));
};
      

Run codeHide result


0


source







All Articles