2012-04-06 8 views
1

In unserem Projekt verwenden wir Google Mock, aber an mehreren Stellen machen wir Konstruktionen in unserem Produktionscode, nur um sicherzustellen, dass Klassen "mockbar" sind. Wir tun dies, weil wir die Vorteile von Google Mock nutzen möchten, aber andererseits möchten wir lieber einen optimalen Produktionscode haben. Der folgende Fall ist etwas, was wir oft machen und gerne loswerden möchten.Wie vermeidet man Zeiger mit Google Mock?

class A{ 
    public: 
    void doSomething(); //Does something with _someB 
    void setSomeB(B* mockedB); //This is only here for GMock 
    private: 
    B* _someB; //This should not be a pointer, it is a pointer only for GMock 
} 

Dies ist nur ein vereinfachtes Beispiel, wie Sie sehen können, habe ich die Details weggelassen. Im Grunde wollen wir loswerden, dass B ein Zeiger ist. Der Grund, warum wir es als Zeiger haben, ist, dass wir B in unserem Testcode ableiten können (mock it) und setzen Sie es mit diesem Setter.

Gibt es eine Möglichkeit, dies zu vermeiden? Können wir nicht zulassen, dass B in der Klasse berücksichtigt wird?

Dank

+0

Verwenden Sie intelligente Zeiger !!! –

+0

@TonyTheLion, die das Objekt immer noch nicht auf dem Stapel leben lässt, es wird immer noch ein Zeiger sein, und ich würde immer noch den Setter brauchen. –

+1

Google ist ziemlich Fan von Dependency-Injektion. Es macht Sinn, dass Sie es schwer haben würden, ihr Testframework ohne dieses Framework zu verwenden. Ich möchte Sie dazu ermutigen, sich ihre YouTube-Videoserie "The Clean Code Talks" anzusehen. Die eine, die die Grundlagen ihrer Unit-Test-Philosophie behandelt, kann hier gefunden werden: http://youtu.be/wEhu57pih5w – cgmb

Antwort

1

Wenn Sie wirklich _someB als Zeiger gehalten nicht wollen, wäre eine Option seine Erklärung in Präprozessorbefehle einzuwickeln:

#ifdef MOCK_TEST 
    B _someB; 
#else 
    MockB _someB; 
#endif 

Wenn Sie dies nicht tun, gibt es keine einfache Möglichkeit, gmock-Erwartungen und/oder Assertions auf _someB zu platzieren, da es keine Instanz eines Mock-Objekts sein wird. Abgesehen von der Hässlichkeit hat dies auch den Nachteil, dass die lib, in der Class A residiert, zweimal kompiliert wird, einmal mit MOCK_TEST definiert und einmal ohne. Es entfällt jedoch die Notwendigkeit eines Setter für _someB.

Auch wenn Sie _someB als Zeiger zu halten, vielleicht eine bessere Option als eine öffentliche Setter schafft, ist die Testklasse ein Freund Klasse von A ist der Test _someB direkt eingestellt und den Zugang zu ermöglichen, zu erklären.


Nebenbei, es ist oft considered poor form Variablen mit einem führenden Unterstrich zu benennen.

+0

Es ist in der Tat ein guter Weg, um den Setter zu arbeiten, aber es erfordert immer noch "speziellen" Code in der Klasse, die das, was ich von der ganzen Zeit loswerden wollte. Ich denke, es gibt einfach keine perfekte Lösung für dieses Problem. Ich werde diese Antwort akzeptieren, wenn es eine "vernünftige" Lösung gibt. Danke für den führenden Unterstrich Kommentar. Ich werde mich sicher daran erinnern! –

+1

@ W.Goeman: Beachten Sie, dass im [Google C++ Style Guide] (http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Variable_Names) als Folge des Problems mit führenden Unterstrichen nachgestellte Unterstriche empfohlen werden . – User