Pourquoi est-GoogleMock fuite de mon shared_ptr?
- Je utiliser GoogleMock/GoogleTest pour les tests, et je vois un comportement étrange quand un matcher a un shared_ptr à un simulacre comme paramètre, et d'en ATTENDRE est appelée sur le même shared_ptr. La délinquance morceau de code:
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
using namespace boost;
using namespace testing;
struct MyParameter
{
virtual ~MyParameter() {}
virtual void myMethod() = 0;
};
struct MyParameterMock : public MyParameter
{
MOCK_METHOD0(myMethod, void());
};
struct MyClass
{
virtual ~MyClass() {}
virtual void myMethod(shared_ptr<MyParameter> p) {}
};
struct MyClassMock : public MyClass
{
MOCK_METHOD1(myMethod, void(shared_ptr<MyParameter>));
};
TEST(LeakTest, GoogleMockLeaksMatchedPointer)
{
shared_ptr<MyClassMock> c = make_shared<MyClassMock>();
shared_ptr<MyParameterMock> p = make_shared<MyParameterMock>();
{
InSequence dummy;
EXPECT_CALL(*c, myMethod(Eq(p)));
EXPECT_CALL(*p, myMethod());
}
c->myMethod(p);
p->myMethod();
}
Lors de ce test, je reçois
leak_ptr_mock.cpp:37: ERROR: this mock object (used in test LeakTest.GoogleMockLeaksMatchedPointer) should be deleted but never is. Its address is @0x9309544.
ERROR: 1 leaked mock object found at program exit.
Une idée de pourquoi cela se produit? Je préfère ne pas avoir à utiliser Mock::AllowLeak
.
Vous devez vous connecter pour publier un commentaire.
C'est un résultat de la tenue de
p
comme unshared_ptr
, à l'aide deInSequence
et l'ordre dans lequel vous avez déclaré vos attentes.Lorsque vous appelez
vous augmentez le
use_count
dep
. Pour la détection de fuite à passer,p
doivent être détruits à l' (ou avant) à la fin deTEST
.Le problème ici est que, en interne, gmock conserve un enregistrement de la nécessaire maquette de la séquence d'appel par la tenue d'un pointeur à la précédente attente. Ainsi, lorsque vous appelez
EXPECT_CALL(*p, myMethod());
, il reçoit une copie du pointeur de la précédente attente.Cette situation a pour effet de bloquer l'appel à
p
's destructeur lorsqueTEST
se termine.Pour contourner ce problème, je pense que votre meilleur pari est d'appeler
juste avant de quitter
TEST
. Cette opération efface les attentes surp
, y compris de façon critique de sa condition attente, ce qui permet à son tour le destructeur dep
être invoquée correctement.Sinon, si l'ordre de la simulation d'appels est sans importance, il suffit de retirer
InSequence dummy;
permettra égalementp
's destructeur pour l'exécuter.En aparté, votre code a un couple de questions;
MyClass::myMethod
devrait être virtuelle afin de permettre gmock de fonction pour le remplacerp->myMethod(p);
devrait êtrep->myMethod();
InSequence dummy;
est utilisé. La permutation de l'ordre de laEXPECT_CALL
s permettrait le test de sortie avec succès, sans fuites, mais si l'ordre des attentes n'a pas d'importance, vous êtes ainsi pas à l'aide deInSequence
à tous. BTW, je suis en utilisant gmock 1.6.0.p
est une struct?