0

次のようなクラスを単体テストしたい:

template <typename T>
class MyClass {
...
    void someMethod() {
        T object;
        object.doSomething();
    }
...
};

このクラスを単体テストしたいので、T のモック クラスを作成します。

struct MockT {
...
    MOCK_METHOD(doSomething, 0, void());
...
};

次に、テスト ケースで使用します。

BOOST_AUTO_TEST_CASE(testSomeMethod) {
    MyClass<MockT> myClassUnderTest;
    MOCK_EXPECT(???)....;
    myClassUnderTest.someMethod();
}

このオブジェクトを期待するにはどうすればよいですか? 私の最初のアイデアは、作成されMockTたすべてのインスタンスをコンストラクターから静的コンテナーに格納し、それらをコンテナーからデストラクタから削除することでした。これは、次のように、オブジェクトが使用されている場所とは異なる方法で作成された場合に機能します。

myClassUnderTest.createTheObject();
MOCK_EXPECT(MockT::findMyObject().doSomething);
myClassUnderTest.useTheObject();

しかし、これにはクラスのインターフェースを変更する必要があり、実際にはそうしたくありません。他にできることはありますか?

4

3 に答える 3

3

インターフェイスを変更したり、余分な間接化を導入したくない場合は、Typemock Isolator++ を使用できます。

template <typename T>
class MyClass
{
public:
    void someMethod()
    {
        T object;
        object.doSomething();
    }
};

    class RealType  //RealType is the actual production type, no injection needed
    {
    public:
        void doSomething(){}
    };

T は someMethod の内部 (テスト メソッドの内部) で作成されるため、T の ctor を偽造する必要があります。FAKE_ALL はまさにそれを行います。fakeRealType に設定された動作は、実行時に作成されるすべての RealType インスタンスに適用されます。デフォルトの FAKE_ALL の動作は再帰的なフェイクです。つまり、すべてのフェイクのメソッドがフェイクされ、フェイク オブジェクトが返されます。任意のメソッドで必要な動作を手動で設定することもできます。

TEST_CLASS(MyTests)
    {
    public:

        TEST_METHOD(Faking_Dependency_And_Asserting_It_Was_Called)
        {
            RealType* fakeRealType= FAKE_ALL<RealType>();
            MyClass<RealType> myClassUnderTest;
            myClassUnderTest.someMethod();

            ASSERT_WAS_CALLED(fakeRealType->doSomething()); 
        }

    };

Typemock フェイクは厳密ではないため、適切な assert を記述して、メソッドが実際に呼び出されたことを確認する必要があります。Typemock にも提供されている ASSERT_WAS_CALLED を使用して実行できます。

PS私はMSTestを使用しました。

于 2015-04-15T08:30:10.493 に答える
1

doSomething メンバー関数を静的関数にリダイレクトできます。

struct MockT
{
    void doSomething() {
        soSomethingS();
    }
    MOCK_STATIC_FUNCTION( doSomethingS, 0, void(), doSomething )
};

次に、あなたのテストは

BOOST_AUTO_TEST_CASE(testSomeMethod) {
    MyClass<MockT> myClassUnderTest;
    MOCK_EXPECT(MockT::doSomething).once();
    myClassUnderTest.someMethod();
}

必要に応じて、オブジェクト インスタンスの構築破棄をテストできますが、それ以上のことはテストにもたらされない可能性があります。

于 2015-03-23T05:34:13.957 に答える