* usually we need test message communication between sub-systems, so the ft maybe looks like following: before refactor::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: struct HeartBeatAckTest : testing::Test { protected: SubSystemA aaa; SubSystemB bbb; Request request; }; TEST_F(HeartBeatAckTest, should_able_to_reply_heart_beat_ack) { MOCKER(shouldReceiveMsg) //using mockcpp .expects(exactly(1)) .with( eq(MSG_HEART_BEAT_ACK) , any() , eq(bbb.address()) , eq(aaa.address())); Msg::send(aaa, bbb, MSG_HEART_BEAT, &request); } //By using operator overload we can make send and receive more easy to read //we can set MOCKER by operator<, --, () and send msg by operator>, --, () after refactor::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #define expects_msg if(true) TEST_F(AckTest, aaa_should_able_to_reply_heart_beat_ack) { expects_msg { aaa<-----bbb(MSG_HEART_BEAT_ACK); } aaa---->bbb(MSG_HEART_BEAT, &request); } TEST_F(AckTest, bbb_should_reply_heart_beat_ack___AND___forward_heart_beat_to_ccc) { expects_msg { aaa<-----bbb(MSG_HEART_BEAT_ACK); ccc<-----bbb(MSG_HEART_BEAT); } aaa---->bbb(MSG_HEART_BEAT, &request); } more thoughts:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: // the <----- is used to set MOCKER before ----->, can we? put the <---- after -----> , // to make the message interaction more easy to comprehensive. // similar to `RAII`, actually we can defer the send message operation of -----> to the end of scope expects_msg. struct SendAllBufferedMessageAtEndOfScope { SendAllBufferedMessageAtEndOfScope(int i) { } //make it can init from dummy int ~SendAllBufferedMessageAtEndOfScope() { send_all_buffered_message_in_sequence(); } operator bool() { return true; } }; #define expects_msg_interaction if (SendAllBufferedMessageAtEndOfScope sendMsgAtEnd = 1) TEST_F(AckTest, should_able_to_reply_heart_beat_ack) { expects_msg_interaction { aaa ----> bbb (MSG_HEART_BEAT, &request); //buffer the messge aaa <---- bbb (MSG_HEART_BEAT_ACK); //set the MOCKER specification //invisible destructor code of sendMsgAtEnd } } TEST_F(AckTest, bbb_should_reply_heart_beat_ack___AND___forward_heart_beat_to_ccc) { expects_msg_interaction { aaa ----> bbb (MSG_HEART_BEAT, &request); aaa <---- bbb (MSG_HEART_BEAT_ACK); ccc <---- bbb (MSG_HEART_BEAT); } } example code:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: struct SubSystemB { SubSystemB& operator--(int) { return *this; } template<typename T> bool operator >(const T& target) { target.receiveMsg(); return true; } }; struct SubSystemA { const SubSystemA& operator()(int msgId, int* p) { msgId_ = msgId; return *this; } void receiveMsg() const { std::cout << "cc got message: " << msgId_ << std::endl; } int msgId_; }; int main(int argc, const char * argv[]) { SubSystemB bbb; SubSystemA aaa; int param = 0; bbb---->aaa(1, ¶m); return 0; } //another example: TEST_F(AckTest, bbb_should_reply_heart_beat_ack___AND___forward_heart_beat_to_ccc) { expects_msg_interaction( op1 ----------------> xx (MSG_HEART_BEAT, &request); op1 <---------------- xx (MSG_HEART_BEAT_ACK); op2 ------------> xx (MSG_HEART_BEAT, &request); op3 --------> xx (MSG_HEART_BEAT, &request); op3 <-------- xx (MSG_HEART_BEAT_ACK); op4 ----> xx (MSG_HEART_BEAT, &request); op4 <---- xx (MSG_HEART_BEAT_ACK); op1 ----------------> xx (MSG_HEART_BEAT, &request); op1 <---------------- xx (MSG_HEART_BEAT_ACK); op2 ------------> xx (MSG_HEART_BEAT, &request); op3 --------> xx (MSG_HEART_BEAT, &request); op3 <-------- xx (MSG_HEART_BEAT_ACK); op4 ----> xx (MSG_HEART_BEAT, &request); op4 <---- xx (MSG_HEART_BEAT_ACK); ); }
2013-10-25
USING operator overload to make your C++ functional test more readable
Subscribe to:
Posts (Atom)