0

以下のクラス C は非常に遅く、単体テストで使用したくないとしましょう。そこで、最終的に C クラスと同じインターフェイスを実装する MockC を作成します。

class IC
{
public:
    virtual std::string getName() = 0;
};

class C: public IC
{
public:
    C(){}
    C(int c) : _c(c){}
    int _c;
    virtual std::string getName()
    {
        // do really slow stuff with an external library
        ...
    }
};

class MockC: public IC
{
public:
    MockC(){}
    MockC(int c) : _c(c){}
    int _c;
    virtual std::string getName()
    {
       ...
    }
};

また、逆参照されたときに Value 型 (C または MockC の可能性があります) のオブジェクトを作成する、簡素化された入力反復子もあります。

template<class Value>
class GetNextIterator 
{
public:
    typedef int (*GetNext)();

    GetNextIterator(GetNext getNext): _getNext(getNext)
    {
        _current = _getNext();
    }

    const Value* operator->() const
    {
        return new Value(_current);
    }

protected:
    int _current;
    GetNext _getNext;
};

int count = 0;
int getNext()
{
    return count++;
}

そして、次のように、Cクラスオブジェクトの親であるが、独自のプロパティも持っている非常に遅い別のクラスがあります。

class ID
{
public:
    virtual std::string getName() = 0;
};

class D: public ID
{
public:
    typedef GetNextIterator<C> Iterator;

    virtual ChildIterator begin() const
    {
        return Iterator(getNext);
    }

    virtual std::string getName()
    {
        // again really slow and accessing external dependencies
        ...
    }
};

例として、次の関数をテストするにはどうすればよいですか。

int f(D* d)
{
    D::ChildIterator i = d->begin();
    if (d.getName() == "something or other")  
        return i->_c;
    else
        return 1;
}

具象クラス C または D を使用したくないことを思い出してください。 f() および同様の関数を完全に単体テストするにはどうすればよいですか? 単体テストでこれを機能させるために、上記のコードを再設計することに完全にオープンです。

4

1 に答える 1

1

モックする必要があるものだけをモックします。の動作をテストするためにf()、重いCオブジェクトをモックアウトすることで正しい方向に進んでいます。処理する必要があると思わf()れる動作をカバーするのに十分なテストケースを作成する必要があります。ただし、コンテナ自体をモックする必要はありません。簡単にテストできるはずです。したがって、IContainerの概念を取り除きます。

ただし、Containerを変更して、具象オブジェクトではなくICオブジェクトの入力を受け入れるようにする必要があります(テストのためだけにContainerがリテラルを保持できる場合は、これをテンプレートベースにする必要もありませんIC*)。テストコードと本番コードの両方が、実際のContainerオブジェクトをに提供しf()ます。テストコードは最初にコンテナをMockCオブジェクトで埋めますが、本番コードはを呼び出す前にコンテナをCオブジェクトで埋めますf()

于 2012-06-26T21:57:53.493 に答える