web-dev-qa-db-fra.com

Google Mock peut-il utiliser une méthode avec un type de renvoi de pointeur intelligent?

J'ai une usine qui renvoie un pointeur intelligent. Quel que soit le pointeur intelligent que j'utilise, je ne peux pas faire en sorte que Google Mock se moque de la méthode d'usine.

L'objet fictif est l'implémentation d'une interface abstraite pure où toutes les méthodes sont virtuelles. J'ai un prototype:

MOCK_METHOD0(Create, std::unique_ptr<IMyObjectThing>());

Et je reçois:

"...gmock/gmock-spec-builders.h(1314): error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'"

Le type pointé dans le pointeur intelligent est défini.

Et j'ai compris que j'essayais d'accéder à l'un des constructeurs déclarés privés, mais je ne comprends pas pourquoi. Quand c'était un std :: auto_ptr, l'erreur disait qu'il n'y avait pas de constructeur de copie, ce qui me confond.

Quoi qu'il en soit, existe-t-il un moyen de simuler une méthode qui renvoie un pointeur intelligent? Ou existe-t-il un meilleur moyen de construire une usine? Est-ce que ma seule résolution est de retourner un pointeur brut (blech ...)?

Mon environnement est Visual Studio 2010 Ultimate et Windows 7. Je n'utilise pas la CLI.

42
Matthew Reddington

Une solution de contournement possible pour résoudre les problèmes de Google Mock Framework avec des arguments de fonction copiables non (const) et des valeurs de réexécution consiste à utiliser des méthodes proxy mock.

Supposons que vous ayez la définition d'interface suivante (si c'est un bon style d'utiliser std::unique_ptr de cette manière, cela semble être plus ou moins une question philosophique, j'aime personnellement le fait d'imposer le transfert de propriété):

class IFooInterface {
public:
    virtual void nonCopyableParam(std::unique_ptr<IMyObjectThing> uPtr) = 0;
    virtual std::unique_ptr<IMyObjectThing> nonCopyableReturn() = 0;
    virtual ~IFooInterface() {}
};

La classe fictive appropriée pourrait être définie comme ceci:

class FooInterfaceMock
: public IFooInterface {
public:
    FooInterfaceMock() {}
    virtual ~FooInterfaceMock() {}

    virtual void nonCopyableParam(std::unique_ptr<IMyObjectThing> uPtr) {
        nonCopyableParamProxy(uPtr.get());
    }
    virtual std::unique_ptr<IMyObjectThing> nonCopyableReturn() {
        return std::unique_ptr<IMyObjectThing>(nonCopyableReturnProxy());
    }


    MOCK_METHOD1(nonCopyableParamProxy,void (IMyObjectThing*));
    MOCK_METHOD0(nonCopyableReturnProxy,IMyObjectThing* ());
};

Vous devez simplement veiller à ce que les configurations (actions entreprises) de la méthode nonCopyableReturnProxy() renvoient soit NULL, soit une instance allouée dynamiquement sur le tas.


Il existe un fil de discussion du forum des utilisateurs google-mock /, dans lequel un des responsables indique que la structure google-mock ne sera pas modifiée pour prendre en charge cette modification, et que leurs règles découragent fortement les paramètres d'utilisation std::auto_ptr. Comme mentionné, il s'agit d'un point de vue philosophique à mon humble avis, et les capacités du cadre moqueur ne devraient pas orienter le type d'interface que vous souhaitez concevoir ou que vous pouvez utiliser à partir d'API tierces.

Comme indiqué, la réponse décrit une solution de contournement réalisable.

92
πάντα ῥεῖ