2016-04-15 3 views
1

を保持モックを書いて、それは次のようになりますは簡単に私がコールバックを多用していくつかのコードをテストしてる状態

class Socket { 
public: 
    void onA(std::function<void()> callBack) = 0; 
    void onB(std::function<void()> callBack) = 0; 
    void onC(std::function<void()> callBack) = 0; 
    void onD(std::function<void()> callBack) = 0; 
    void onE(std::function<void()> callBack) = 0; 

    // various other public methods 
}; 

Clientの状態変化するのでそれは(私はonX関数が呼び出されたことを確認し、それに渡された引数へのアクセスを得ることができ、両方のことが重要です:のように見えますSocket、私のテストでそれらをシミュレートする必要があります)。関数を呼び出す今、「このMockSocketオブジェクトはそのonAメソッドが一度呼ばれていたことを期待する:私は、フォームの期待を書くことができるようにする必要があり

class MockSocket : public Socket { 
public: 
    MOCK_METHOD1(onA, void(std::function<void()> callBack)); 
    MOCK_METHOD1(onB, void(std::function<void()> callBack)); 
    // etc 
}; 

しかし:

私は次のようになりますモックを書くことができますそれはonAに引数として渡された今Socketwriteメソッドがこの文字列で呼び出されたことを確認します。私は、この種の唯一の機能を持っていたとき...」別のケースで

は、私のような何かをしました:

class MockSocket : public Socket { 
public: 
    // as before 

    void setCallbackForA(std::function<void()> callBack) { 
    callbackForA = callBack; 
    } 

    void callCallbackForA() { 
    callbackForA(); 
    } 

    // etc 

private: 
    std::function<void()> callbackForA; 
    std::function<void()> callbackForB; 
    // etc 
}; 

しかし、それは(非常にわずかテストケースからテストケースにするだろう5つのゲッターと5つのセッター+ EXPECT_CALL Sの全て、)これ行わを取得するための定型のとんでもない量になるだろう、と私はそこになければならないことを疑いますこれを行うためのより良い方法です(Cスタイルのマクロに頼らずに)。いくつかのテンプレートマジックが役立つでしょうか?それを少し扱いやすくするための何か?

答えて

2

Clientクラスをテストしていると仮定します。実際に必要なのはClientが登録するコールバック関数をSocketに保存することです。これを行うには、SaveArg<N>アクションを実行します。コードを参照してください:

class ClientTest : public ::testing::Test 
{ 
public: 
    std::function<void()> onACallback; 
    std::function<void()> onBCallback; 
    //... 
    MockSocket mockSocket; 
    std::unique_ptr<Client> objectUnderTest; 
    void SetUp() override 
    { 
     using ::testing::SaveArg; 
     EXPECT_CALL(mockSocket, onA(_)).WillOnce(SaveArg<0>(&onACallback)); 
     EXPECT_CALL(mockSocket, onB(_)).WillOnce(SaveArg<0>(&onBCallback)); 
     //... 
     objectUnderTest = std::make_unique<Client>(mockSocket); 

    } 
}; 

上記のテストクラスでは、すべてのコールバックを収集できます。また、これらのキャッチされたコールバックを使用して、以下のテストケースのようにクライアントクラスのアクションをトリガーすることができます:

TEST_F(ClientTest, shallDoThisAndThatOnA) 
{ 
    // here you put some expectations 
    //... 
    onACallback(); // here you trigger your Client object under test 
    // now you make some assertions (post actions) 
    //... 
} 
関連する問題