2016-07-28 31 views
0

Im Beispiel unten mag ich Unit-Test class A, um das zu überprüfen, wenn A::request genannt wird, B::response() auch genannt wird:Google Test Framework: Ist es besser, Shadowing oder virtuelle Methoden zu verwenden?

class A 
{ 
public: 
    void request() 
    { 
     m_b.response(); 
    } 

private: 
    B m_b; 
}; 

class B 
{ 
public: 
    void response(); 
}; 

Um das zu tun, class B verspottet werden muss:

class MockB : public B 
{ 
public: 
    MOCK_METHOD0(response, void()); 
}; 

Damit der Test enthält:

class TestA : public A 
{ 
    ... 
}; 

... 
EXPECT_CALL(m_b, response()).Times(1); 
request(); 
... 

die Frage i s: wie "MockB als Ersatz für B m_b" injizieren?

Erste tecnique: eine ShadowB Klasse erstellen, die den Methodenaufruf zu class MockB umleitet. Dies erfordert, dass sich der ursprüngliche Code in einer externen Binärdatei befindet, aber keine Änderung des tatsächlichen Codes erfordert.

Zweiter tecnique:

  • macht B::responsevirtual
  • Ändern B m_b zu einem std::unique_ptr<B> m_b
  • ersetzen m_b Wert mit einer Instanz von class MockB während des Testaufbaus

Zweiter Ansatz mea ns mehr Code ändern und ich bin mir nicht sicher über seinen Profi.

Antwort

1

Die richtige Methode zur Lösung Ihres Problems ist die zweite Technik. Ganz allgemein ist es sehr schwierig, Unit-Test-Code auf Komponenten zu "nachrüsten", die nicht dafür konzipiert wurden - Sie müssen den zu testenden Code fast immer erheblich modifizieren.

Mit virtuellen Funktionen ersetzen Mock-Callback-Objekte anstelle von realen, beide erben von einer gemeinsamen Schnittstelle ist ein sehr gängiger Ansatz. Eine andere Alternative besteht darin, dass Ihre getesteten Klassen Vorlagenklassen sind und ihre Vorlagenparameter durch Mock-Objekte ersetzen.

+0

Sie schlagen also im Grunde einen testgetriebenen Designansatz vor. Sehr interessant die Schablonentechnik. Das würde übrigens einen großen Einfluss auf den Code haben (viel Code, der in Header- und Inline-Dateien verschoben werden muss). – nyarlathotep108

+0

Ja, ich mag viele Aspekte des testgetriebenen Designs, obwohl ich es nicht religiös befolge. Ich denke jedoch, dass selbst wenn Sie keinen Komponententest für jedes kleine Szenario erstellen, das möglicherweise vor dem Schreiben der Implementierung passieren könnte (was TDD Ihnen predigen sollte), werden Sie immer noch feststellen, dass das Testen als Nachsatz sehr schwierig ist etwas ernsthaftes Code-Redesign - man kann einfach nicht davon wegkommen, Testen ist aufdringlich. Persönlich mag ich fast alles, was ich schreibe, damit ich Mock-Template-Parameter anwenden kann – Smeeheey