クラスA
をテストしていて、 の依存性注入をB
持つ依存性注入があるとしC
ます。
だからあなたはモックしますB
が、それが持っている唯一のコンストラクターは の注入を必要とします。5 つの連続した依存関係がある場合はどうなりますか?C
C
C
B
A
代替手段は何ですか?
私はGoogle Mockを使用しているので、特定の回答も役立ちます。
クラスA
をテストしていて、 の依存性注入をB
持つ依存性注入があるとしC
ます。
だからあなたはモックしますB
が、それが持っている唯一のコンストラクターは の注入を必要とします。5 つの連続した依存関係がある場合はどうなりますか?C
C
C
B
A
代替手段は何ですか?
私はGoogle Mockを使用しているので、特定の回答も役立ちます。
エミールは正しい考えを持っています。具体的なクラスではなく、インターフェイスに依存する必要があります。したがって、あなたの例では次のようになります。
#include <iostream>
using namespace std;
class C {
public:
int x;
};
class B {
public:
~B(){};
virtual void doSomething() = 0;
};
class ConcreteB : public B{
public:
ConcreteB(C c) : m_c(c) {}
void doSomething(){
std::cout << "HelloWorld" << std::endl;
}
private:
C m_c;
};
class A{
public:
A(B *b): m_b(b){}
void functionToTestWithSideEffect(){
m_b->doSomething();
}
private:
B *m_b;
};
//#include <gmock/gmock.h>
int main() {
C c;
c.x = 42;
ConcreteB b(c);
A a(&b);
a.functionToTestWithSideEffect();
return 0;
}
テストでは、クラス C に依存しないモック B を作成します。次に、B とのインターフェイスのみをテストします。このようにして、A の C への依存を断ち切ります。C に依存しないモック B を作成するのはかなり簡単です。単純:
class MockB : public B {
public:
MOCK_METHOD0(doSomething, void());
};
クラスが具象クラスではなくインターフェイスに依存するように設計を変更すると、コンストラクターの問題が解消されます。テスト容易性が向上するだけでなく、再利用性と保守性も向上する可能性がありますが、コード (インターフェース) が増えます。
この場合、参照ではなくポインターによって注入する必要があり、NULL ポインターを渡すことができます。これは、オブジェクトが実際にモックであり、偽のオブジェクトではない場合に機能するため、注入されたオブジェクトに実際の依存関係はありません。
次のboost::shared_ptr
ことができます。
boost::shared_ptr<C> null_c_ptr;
MockB mock_b(null_c_ptr);