Utiliser google mock pour le code C

je maintiens un projet d'héritage écrit en c/" class="blnk">C et il est impossible de le faire tourner avec un compilateur C++. Puisque le code est compilé en croix, il est cependant possible d'exécuter des tests unitaires ou similaires dans un environnement hôte. il est donc également possible de s'interfacer avec un compilateur hôte C++ et d'utiliser google-test et google-mock.

il y a certaines fonctionnalités de google-mock qui semblent être très tentantes à utiliser pour tester l'invocation d'implémentations réelles et la définition d'appel attente.

je voudrais pouvoir les utiliser en code C. Je peux voir qu'il est en effet possible d'utiliser google-mock sans utiliser vtables, mais cela nécessite des modèles.

Existe-t-il un moyen de simuler des fonctions en C nu avec Google mock?

17
demandé sur Alex 2013-10-24 01:38:50

3 réponses

j'ai trouvé un moyen de pouvoir simuler des fonctions C dans google-mock.

La solution est de déclarer foobar faible alias cartes foobarImpl. Dans le code de production vous n'implémentez pas foobar() et pour les tests unitaires vous fournissez une implémentation qui appelle un objet simulé statique.

cette solution est spécifique à GCC mais il y a d'autres compilateurs/linkers qui fournissent un aliasing faible.

  • renommer la fonction void foobar(); pour void foobarImpl();
  • ajouter un attribut à la fonction foobar comme: void foobar() __attribute__((weak, alias("foobarImpl") ));
  • si vous voulez avoir un alias non faible, utilisez une directive preproessor pour supprimer le faible des attributs.

D'où:

#pragma once
void foobar();

devient

// header.h
#pragma once

void foobar();    
void foobarImpl(); // real implementation

et

extern "C" {
#include "header.h"
}
// code.c
void foobarImpl() {
  /* do sth */
}
void foobar() __attribute__(( weak, alias ("foobarImpl") )); // declare foobar to be a weak alias of foobarImpl

ceci indiquera au gnu linker de lier les appels de foobar()foobarImpl() quand il n'y a pas de symbole appelé foobar()

puis ajouter le test code

struct FooInterface {
   virtual ~FooInterface() {}
   virtual void invokeFoo() const { }
};

class MockFoo : public FooInterface {
public:
  MOCK_CONST_METHOD0(invokeFoo, void());
}

struct RealFoo : public FooInterface {
   virtual ~RealFoo() {}
   virtual void invokeFoo() const { foobarImpl(); }
};

MockFoo mockFoo;
RealFoo realFoo;
void foobar() {
  mockFoo.invokeFoo();
}

si ce code est compilé et lié il remplacera foobar avec le simulacre d'appel. si vous voulez vraiment appeler foobar() vous pouvez toujours ajouter une invocation par défaut.

ON_CALL(mockFoo, invokeFoo())
       .WillByDefault(Invoke(&realFoo,&RealFoo::invokeFoo));
13
répondu Alex 2018-01-13 20:47:34

à partir de Google se Moquer de la FAQ:

mon code appelle une fonction statique / globale. Puis-je s'en moquer?

Vous pouvez, mais vous devez faire quelques changements.

en général, si vous devez simuler une fonction statique, c'est un signe que vos modules sont trop étroitement couplés (et moins flexibles, moins réutilisables, moins testables, etc.). Vous êtes probablement mieux de définir une petite interface et appeler la fonction à travers cette interface, ce qui peut facilement être moqué. C'est un peu de travail au début, mais généralement rapidement rentabilisé.

Ce Blog Google Testing post dit bien. Check it out.

2
répondu πάντα ῥεῖ 2013-10-23 21:43:29

votre question mentionne expressément Google Mock, mais ne mentionne aucune autre raison d'utiliser ce framework. L'autre réponse suggère d'utiliser une solution de contournement qui semble inutilement intrusif.

C'est pourquoi j'espère être autorisé à faire une suggestion alternative qui fonctionne bien sans avoir à utiliser des alias faibles, etc.

j'ai utilisé CppUTest (https://cpputest.github.io/) pour l'essai unitaire avec mock, avec succès sur un couple de grands principalement-C projets (certains c++). La moquerie fonctionne sans avoir à recourir à n'importe quel subterfuge de la sorte ci-dessus.

malheureusement la documentation du projet est un peu faible, un peu meilleure (si un peu agile-doctrinaire) information et exemples dans le livre (également vu circulant comme un PDF) "Test Driven Development for Embedded C" - James W Greening (ISBN-13: 978-1-934356-62-3)

2
répondu MikeW 2016-11-21 11:41:22