assertEventually
Growing Object-Oriented Software, Guided by Tests (Addison-Wesley Signature Series (Beck))で紹介されていた assertEventually を実装した。これは何かというと「非同期の Unit Test で結果が期待されるものになるまでポーリングする」 assert 。
紹介されていた実装では「ポーリング」を実装した Poller クラスと「期待された状態をチェックする」 Probe インターフェースを定義していてうまく抽象化されている。
利用方法
今回は terminal の出力に特定の文字列が現れるかどうか?をタイムアウト付きでテストした。まず Probe のサブクラスで「期待された状態をチェック」するコードを書く。
class TerminalOutputProbe : public Probe { private: TestTerminal& terminal_; std::string lastContent_; std::string contentToMatch_; public: TerminalOutputProbe(TestTerminal& terminal, const std::string& contentToMatch) : terminal_(terminal), contentToMatch_(contentToMatch) { } void sample() { lastContent_ = terminal_.getOutput(); } bool isSatisfied() { return lastContent_.find(contentToMatch_) != std::string::npos; } void describeTo(std::string& d) { d += "<"; d += contentToMatch_; d += ">"; } void describeFailureTo(std::string& d) { d += "<"; d += lastContent_; d += "> "; } };
あとは以下のように ASSERT_EVENTUALLY に渡すだけ。ASSERT_EVENTUALLY が大文字になっているのは __FILE__, __LINE__ を assertEventually に渡すため。
TerminalOutputProbe probe(*testTerminal, "HELLO.EX5");
ASSERT_EVENTUALLY(probe);