2017-05-11 1 views
3

Comment utiliser gmock pour simuler une méthode de modèle (pas une classe de modèle) pour une classe? Exemple d'une classe comme ça, je veux moquer cette classe, et cette méthode de modèle ..Comment utiliser gmock pour simuler une méthode de modèle d'une classe?

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

Je sais comment se moquer une classe avec des méthodes non virtuelles, ou se moquer d'une classe templated , mais je ne sais pas comment se moquer une classe non basé sur un modèle avec une méthode .. templated

+1

Pour votre information: fonction modèle (méthode) ne peut pas être virtuel en C++ - donc ne pas avoir besoin d'ajouter à la description du modèle de fonction qu'il n'est pas – PiotrNycz

+0

oups virtuel grâce. mon erreur –

Répondre

2
  1. Première solution beaucoup mieux est d'utiliser la mise en œuvre de cette fonction A::getType - peut-être ne pas être moqué? Par exemple: si elle retourne juste une valeur qui est définie dans le constructeur - puis juste construire A de la manière qui est nécessaire dans votre cas de test:
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. Si elle ne peut pas faire de cette façon - alors vous pourriez envisager d'avoir une instrumentation pour UT qui est commuté avec des macros préprocesseur:
#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); 
     ... 
} 

en ce qui concerne le point-2 - bien sûr, tout code de test doit être soigneusement séparé du « code normal » - par exemple dans certains fichiers d'en-tête séparés.

Il est intéressant de noter qu'aucune de ces solutions n'est parfaite - et cette deuxième solution pourrait ne pas être fiable à 100% car vous ne testeriez pas de vrai code mais une version testable. Peut-être devriez-vous commencer par repenser votre conception, car il semble que le design n'ait pas été complété avec "design for testability".

+0

la signature de fonction était un exemple factice. Ne pensez pas que l'une ou l'autre solution me convient. mais merci. –

0

I finissent par faire un relais de railler la méthode

Par ex

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