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::response
virtual
- Ändern
B m_b
zu einemstd::unique_ptr<B> m_b
- ersetzen
m_b
Wert mit einer Instanz vonclass MockB
während des Testaufbaus
Zweiter Ansatz mea ns mehr Code ändern und ich bin mir nicht sicher über seinen Profi.
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
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