あなたにはいくつかの選択肢があると思います。あなたが言うように、一つの選択肢はインターフェースを作ることです。あなたがインターフェイスを導入するためのクラス
class Engine:
{
public:
void start(){ };
};
class Car
{
public:
void start()
{
// do car specific stuff
e_.start();
private:
Engine e;
};
を持っていると言う - あなたは突然、あなたの車を作った - あなたがエンジンのみの1種類を持っている場合は、エンジン
を取るために車を変更する
class Car
{
public:
Car(Engine* engine) :
e_(engine)
{}
void start()
{
// do car specific stuff
e_->start();
private:
Engine *e_;
};
を持っているでしょうオブジェクトを使用するのが難しい(エンジンを作成する人、エンジンを所有する人)。車は部品が多いので、この問題は引き続き増加します。
個別の実装が必要な場合は、別の方法としてテンプレートを使用することができます。これにより、インタフェースが不要になります。あなたのモックで
class Car<type EngineType = Engine>
{
public:
void start()
{
// do car specific stuff
e_.start();
private:
EngineType e;
};
、あなたがして、特殊なエンジンを搭載した車を作成することができます。
Car<MockEngine> testEngine;
もう一つ、別のアプローチを、それをテストすることができるようにするためにエンジンにメソッドを追加することであろう、のようなもの:
class Engine:
{
public:
void start();
bool hasStarted() const;
};
次に、車にチェックメソッドを追加するか、車からテストに継承することができます。
class TestCar : public Car
{
public:
bool hasEngineStarted() { return e_.hasStarted(); }
};
これは、EngineをCarクラスのprivateからprotectedに変更する必要があります。
実際の状況によっては、どのソリューションが最適かによって異なります。また、各開発者は、コードが単体テストされるべきであると考える方法について、それぞれ独自の聖杯を持っています。私の個人的な見解はクライアント/顧客を念頭に置いておくことです。あなたのクライアント(おそらく、あなたのチームの他の開発者)が車を作り、エンジンについて気にしないと仮定しましょう。したがって私はエンジンの概念(私の図書館の内部のクラス)を公開したくないので、単体テストをテストすることができます。私はインターフェイスを作成せず、2つのクラスを一緒にテストすることを選択します(私が与えた3つ目のオプション)。
ありがとうございます。私はそれをgrokしようとしています。ホワイトボックステストはモックに適していないと言っていますか?私が単体テストを見ているのは、私が各コードユニットをテストしようとしていることです。たとえば、私は 'Car'をテストしたい、' Car'は 'Engine'クラスに依存します。 *統合テストではなく、* unit *テストを確実に行うために、 'Engine'クラスをモックする必要があります(私のモックされた' Engine'を使うために 'Car'を取得します) 。それ以外の場合、私は2つのクラスをテストしており、ユニットテストではなく統合テストを行っています。そして、 'Engine'クラスを簡単に模擬するためには、それがインタフェースである必要があるようです。 – User
ここで唯一の違いは、*単位*が表すことです。通常、テスト対象のユニットはコンパイルユニットまたはクラスを表しますが、そのようにする必要はありません。たとえば、グラフクラスを作成すると、ノードとエッジが強く結合しているため、それらを孤立してテストするのは非常に意味がありません。ファサードインターフェイスにグラフモジュール全体をラップするだけで、他のモジュールがグラフの模擬表現とやりとりする必要があるときは、個々のクラスではなくグラフファサードをモックする(適切なファサードとして、APIレベルのノード整数またはid) – lurscher
私は単体テストについて理解していますが、エッジクラスがノードクラスを使用する場合は、エッジクラスをテストするときにノードクラスをモックしたいと思います。なぜなら、2つの "ユニット"同時に。エッジクラスのテストが失敗した場合、本当に失敗したエッジまたはノードであるかどうかはわかりません。私は、あなたが統合テストについて話していることを呼ぶと思います(それはある程度のセマンティクスであることに気がつきます)。 – User