C++单测总结(gtest、gmock和mockcpp)
2019-08-14 12:26
10943 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/tangchuanhui/article/details/99552866
- 为了能对类成员进行mock,把类的成员变量声明为shared_ptr
- gmock仅支持对虚函数的mock,需要mock的成员函数都声明为虚函数
- 优先使用gmock,仅静态方法的mock使用mockcpp
- 在单测中需要直接修改对象成员变量以构造数据,在单测cpp文件最开头加上以下2个宏,就可以直接访问任何成员
[code]#include <memory> #include <gmock/gmock.h> #define private public #define protected public #include <common/context/service_context.h>
资料参考:
https://www.geek-share.com/detail/2674567760.html
https://www.geek-share.com/detail/2450012840.html
https://www.cnblogs.com/welkinwalker/archive/2011/11/29/2267225.html
https://www.geek-share.com/detail/2692161500.html
https://www.geek-share.com/detail/2619675509.html
下面是一个例子:
[code]// event.h #ifndef ZHANGQIAN_RECONCILIATION_MESSAGE_PAAS2WW_PAAS_WW_MSGREAD_EVENT_H_ #define ZHANGQIAN_RECONCILIATION_MESSAGE_PAAS2WW_PAAS_WW_MSGREAD_EVENT_H_ #include <string> #include "reconciliation/base_event.h" namespace WWS { class Paas2WwMsgReadEvent:public BaseEvent { public : Paas2WwMsgReadEvent(const std::string& topic, const std::string& tag, const std::string& data); virtual ~Paas2WwMsgReadEvent(); virtual int32_t Parse(); virtual int32_t Filter(); virtual boost::shared_ptr<BCPResult<void> > Verify(); IMPaaSMessageReadEvent paas_msg_read_; }; } // namespace WWS #endif // ZHANGQIAN_RECONCILIATION_MESSAGE_PAAS2WW_PAAS_WW_MSGREAD_EVENT_H_
[code]// event.cpp #include "reconciliation/message/paas2ww/paas_ww_msgread_event.h" #include <wws/json.h> #include <itf/aqdatadef.h> #include <ice_client.h> #include <vector> #include <StringUtil.h> #include <UserManager.h> #include <MsgIdManager.h> #include <LoulanComm.h> #include <JsonUtil.h> #include <LoulanStruct.h> #include "reconciliation/hsfclient/reconciliation_hsf_client.h" #include "reconciliation/util/event_util.h" namespace WWS { Paas2WwMsgReadEvent::Paas2WwMsgReadEvent( const std::string& topic, const std::string& tag, const std::string& data): BaseEvent(topic, tag, data) {} Paas2WwMsgReadEvent::~Paas2WwMsgReadEvent() {} int32_t Paas2WwMsgReadEvent::Parse() { if (!WWS::wwsFromJson(data_, paas_msg_read_)) { ErrLog(__FUNCTION__ << " failed, data is not a valid json, data:" << data_); return PROCESS_STOP; } return PROCESS_SUCCESS; } int32_t Paas2WwMsgReadEvent::Filter() { if (paas_msg_read_.msgIds.empty()) { ErrLog(__FUNCTION__ << " msgId is empty, paas_msg_read_.json=" << wws::json::toJson(paas_msg_read_)); return PROCESS_STOP; } StringMap::const_iterator iter = paas_msg_read_.ctx.find(KEY_SOURCE); if (iter != paas_msg_read_.ctx.end() && KEY_FROM_WW == iter->second) { DebugLog(__FUNCTION__ << " metaq is form ww, so is filtered."); return PROCESS_STOP; } return PROCESS_SUCCESS; } boost::shared_ptr<BCPResult<void> > Paas2WwMsgReadEvent::Verify() { ::AliIMMsg::SMsgMetaSeq keys; bool has_once_fail = false; bool has_once_need_retry = false; int32_t ret; for (vector<string>::iterator it = paas_msg_read_.msgIds.begin(); it != paas_msg_read_.msgIds.end(); it++) { ret = GetWwMsgInfoAndPutToVector(*it, keys); if (ret == PROCESS_NEED_RETRY) { has_once_need_retry = true; } else if (ret == PROCESS_FAIL) { has_once_fail = true; } } if (has_once_fail) { return BCPResult<void>::GetFailedResult( RECONCILIATION_FAIL, "GetWwMsgInfoAndPutToVector failed."); } if (has_once_need_retry) { return BCPResult<void>::GetFailedResult( RECONCILIATION_RETRY, "GetWwMsgInfoAndPutToVector failed, need retry."); } ::AliIMMsg::SBinaryMsgEx2Seq ans; ret = IceProxyClient::get()->GetMsgInfo(keys, ans); if (ret != 0) { if (isIceError(ret)) { return BCPResult<void>::GetFailedResult( RECONCILIATION_RETRY, "GetMsgInfo failed, need retry."); } return BCPResult<void>::GetFailedResult( RECONCILIATION_FAIL, "GetMsgInfo failed."); } if (ans.size() != keys.size()) { ErrLog(__FUNCTION__ << " failed, ans.size() = " << ans.size() << " keys.size() = " << keys.size()); return BCPResult<void>::GetFailedResult( RECONCILIATION_FAIL, "GetMsgInfo failed, ans.size() = " + StringUtil::toString(ans.size()) + " keys.size() = " + StringUtil::toString(keys.size())); } bool has_msg_not_read = false; for (int32_t i = 0; i < ans.size(); ++i) { if (ans[i].readFlag == 0) { has_msg_not_read = true; ErrLog(__FUNCTION__ << " failed, fromId=" << ans[i].fromId << " toId=" << ans[i].toId << " msg.uuid=" << ans[i].uuid << " is not be read in ww"); } } if (has_msg_not_read == true) { return BCPResult<void>::GetFailedResult( RECONCILIATION_FAIL, "some message in ww is't been read"); } return BCPResult<void>::GetSuccessResult(); } } // namespace WWS
[code]// Mock.h #ifndef ZHANGQIAN_UTEST_MOCK_RECONCILIATION_MESSAGE_PAAS2WW_PAAS_WW_MSGREAD_EVENT_MOCK_H_ #define ZHANGQIAN_UTEST_MOCK_RECONCILIATION_MESSAGE_PAAS2WW_PAAS_WW_MSGREAD_EVENT_MOCK_H_ #include <gtest/gtest.h> #include <gmock/gmock.h> #include <string> #include "reconciliation/message/paas2ww/paas_ww_msgread_event.h" namespace WWS { class Paas2WwMsgReadEventMock : public Paas2WwMsgReadEvent { public: Paas2WwMsgReadEventMock( const std::string& topic, const std::string& tag, const std::string& data): Paas2WwMsgReadEvent(topic, tag, data) { } MOCK_METHOD0(Parse, int32_t()); MOCK_METHOD0(Filter, int32_t()); MOCK_METHOD0(Verify, boost::shared_ptr<BCPResult<void> >()); int32_t ConcretParse() { return Paas2WwMsgReadEvent::Parse(); } int32_t ConcretFilter() { return Paas2WwMsgReadEvent::Filter(); } boost::shared_ptr<BCPResult<void> > ConcretVerify() { return Paas2WwMsgReadEvent::Verify(); } }; } // namespace WWS #endif // ZHANGQIAN_UTEST_MOCK_RECONCILIATION_MESSAGE_PAAS2WW_PAAS_WW_MSGREAD_EVENT_MOCK_H_
[code]// test.cpp #define private public #define protected public #include <gtest/gtest.h> #include <gmock/gmock.h> #include <iostream> #include <string> #include <list> #include <fstream> #include <LoulanStruct.h> #include <boost/make_shared.hpp> #include <MsgIdManager.h> #include "loulan/paas_client.h" #include "loulan/Use 3ff7 rManager.h" #include "LoulanDefine.h" #include "mockcpp/MockObject.h" #include "mockcpp/mockcpp.h" #include "mockcpp/mokc.h" #include "utest/mock/client/ice_client_mock.h" #include "reconciliation/util/event_util.h" #include "utest/mock/reconciliation/message/paas2ww/paas_ww_msgread_event_mock.h" namespace WWS { using ::testing::Return; using ::testing::SetArgReferee; using ::testing::DoAll; class Paas2WwMsgReadEventTest: public ::testing::Test { public: static void SetUpTestCase() {} static void TearDownTestCase() {} virtual void SetUp(); virtual void TearDown(); virtual void ReadDataFromFile(const std::string& file); boost::shared_ptr<class Paas2WwMsgReadEventMock> paas2ww_msg_read_event_mock_; std::string topic; std::string tag; std::string data; }; void Paas2WwMsgReadEventTest::ReadDataFromFile(const std::string& file) { topic = "mocktopic"; tag = "mocktag"; data = ""; std::ifstream is(file.c_str(), std::ifstream::binary); if (is) { // get length of file: is.seekg(0, is.end); int length = is.tellg(); is.seekg(0, is.beg); char * buffer = new char[length]; // read data as a block: is.read(buffer, length); for (int32_t i = 0; i < length; ++i) { data += buffer[i]; } if (!is) { std::cout << "error: only " << is.gcount() << " could be read"; } is.close(); delete[] buffer; } else { std::cout << "open file failed" << std::endl; } paas2ww_msg_read_event_mock_.reset( new Paas2WwMsgReadEventMock(topic, tag, data)); } void Paas2WwMsgReadEventTest::SetUp() { GlobalMockObject::reset(); ReadDataFromFile("utest/reconciliation/message/paas2ww/testdata/paas_ww_msgread_right_data.txt"); } void Paas2WwMsgReadEventTest::TearDown() { GlobalMockObject::verify(); } TEST_F(Paas2WwMsgReadEventTest, ParseFailDataIsInvalid) { topic = "mocktopic"; tag = "mocktag"; data = "mockdata"; paas2ww_msg_read_event_mock_.reset(new Paas2WwMsgReadEventMock(topic, tag, data)); int ret = paas2ww_msg_read_event_mock_->ConcretParse(); ASSERT_TRUE(0 != ret); } TEST_F(Paas2WwMsgReadEventTest, ParseSuccess) { int ret = paas2ww_msg_read_event_mock_->ConcretParse(); ASSERT_TRUE(0 == ret); } TEST_F(Paas2WwMsgReadEventTest, FilterFailMsgIdsIsEmpty) { paas2ww_msg_read_event_mock_->paas_msg_read_.msgIds.clear(); int ret = paas2ww_msg_read_event_mock_->ConcretFilter(); ASSERT_TRUE(0 != ret); } TEST_F(Paas2WwMsgReadEventTest, FilterFailMqFromWw) { ReadDataFromFile("utest/reconciliation/message/paas2ww/testdata/paas_ww_msgread_filter_data.txt"); int ret = paas2ww_msg_read_event_mock_->ConcretParse(); ASSERT_TRUE(0 == ret); ret = paas2ww_msg_read_event_mock_->ConcretFilter(); ASSERT_TRUE(0 != ret); } TEST_F(Paas2WwMsgReadEventTest, FilterSuccess) { int ret = paas2ww_msg_read_event_mock_->ConcretParse(); ASSERT_TRUE(0 == ret); ret = paas2ww_msg_read_event_mock_->ConcretFilter(); ASSERT_TRUE(0 == ret); } TEST_F(Paas2WwMsgReadEventTest, VerifyFailGetWwMsgInfoAndPutToVectorReturnRetry) { paas2ww_msg_read_event_mock_->paas_msg_read_.msgIds.push_back("msgid1"); paas2ww_msg_read_event_mock_->paas_msg_read_.msgIds.push_back("msgid2"); ::AliIMMsg::SMsgMetaSeq keys; ::AliIMMsg::MsgMeta key_one; keys.push_back(key_one); keys.push_back(key_one); MOCKER(&GetWwMsgInfoAndPutToVector) // mock静态方法 .stubs() .with(any(), outBound(keys)) // 绑定出参 .will(returnObjectList(0, 1)); // 1 PROCESS_NEED_RETRY boost::shared_ptr<BCPResult<void> > result = paas2ww_msg_read_event_mock_->ConcretVerify(); ASSERT_TRUE(result->success == false && result->code == RECONCILIATION_RETRY); } TEST_F(Paas2WwMsgReadEventTest, VerifyFailGetWwMsgInfoAndPutToVectorReturnFail) { paas2ww_msg_read_event_mock_->paas_msg_read_.msgIds.push_back("msgid1"); paas2ww_msg_read_event_mock_->paas_msg_read_.msgIds.push_back("msgid2"); ::AliIMMsg::SMsgMetaSeq keys; ::AliIMMsg::MsgMeta key_one; keys.push_back(key_one); keys.push_back(key_one); MOCKER(&GetWwMsgInfoAndPutToVector) .expects(exactly(2)) .with(any(), outBound(keys)) .will(returnValue(0)) .then(returnValue(-1)); // -1 PROCESS_FAIL boost::shared_ptr<BCPResult<void> > result = paas2ww_msg_read_event_mock_->ConcretVerify(); ASSERT_TRUE(result->success == false && result->code == RECONCILIATION_FAIL); } TEST_F(Paas2WwMsgReadEventTest, VerifyFailSizeOfkeysAndAnsNE) { paas2ww_msg_read_event_mock_->paas_msg_read_.msgIds.push_back("msgid1"); paas2ww_msg_read_event_mock_->paas_msg_read_.msgIds.push_back("msgid2"); ::AliIMMsg::SMsgMetaSeq keys; ::AliIMMsg::MsgMeta key_one; keys.push_back(key_one); keys.push_back(key_one); MOCKER(&GetWwMsgInfoAndPutToVector) .stubs() .with(any(), outBound(keys)) .will(returnValue(0)) .then(returnValue(0)); ::AliIMMsg::SBinaryMsgEx2Seq ans; ::AliIMMsg::BinaryMsgEx2 ans_one; ans_one.readFlag = 1; ans.push_back(ans_one); // mock单例对象的函数 IceProxyClientMock kIceProxyClientMock; IceProxyClientMock::swap(&kIceProxyClientMock); EXPECT_CALL(kIceProxyClientMock, GetMsgInfo(::testing::_, ::testing::_)) .Times(1) .WillOnce(DoAll(SetArgReferee<1>(ans), Return(0))); boost::shared_ptr<BCPResult<void> > result = paas2ww_msg_read_event_mock_->ConcretVerify(); ASSERT_TRUE(result->success == false && result->code == RECONCILIATION_FAIL); } TEST_F(Paas2WwMsgReadEventTest, VerifyFailMsgNotRead) { paas2ww_msg_read_event_mock_->paas_msg_read_.msgIds.push_back("msgid1"); paas2ww_msg_read_event_mock_->paas_msg_read_.msgIds.push_back("msgid2"); ::AliIMMsg::SMsgMetaSeq keys; ::AliIMMsg::MsgMeta key_one; keys.push_back(key_one); keys.push_back(key_one); MOCKER(&GetWwMsgInfoAndPutToVector) .stubs() .with(any(), outBound(keys)) .will(returnValue(0)) .then(returnValue(0)); ::AliIMMsg::SBinaryMsgEx2Seq ans; ::AliIMMsg::BinaryMsgEx2 ans_one; ans_one.readFlag = 0; ans.push_back(ans_one); ans.push_back(ans_one); IceProxyClientMock kIceProxyClientMock; IceProxyClientMock::swap(&kIceProxyClientMock); EXPECT_CALL(kIceProxyClientMock, GetMsgInfo(::testing::_, ::testing::_)) .Times(1) .WillOnce(DoAll(SetArgReferee<1>(ans), Return(0))); // 绑定引用出参 // // 绑定指针出参是 bool mute; // SetArgPointee<2>(mute) // boost::shared_ptr<BCPResult<void> > result = paas2ww_msg_read_event_mock_->ConcretVerify(); ASSERT_TRUE(result->success == false && result->code == RECONCILIATION_FAIL); } TEST_F(Paas2WwMsgReadEventTest, VerifySuccess) { paas2ww_msg_read_event_mock_->paas_msg_read_.msgIds.push_back("msgid1"); paas2ww_msg_read_event_mock_->paas_msg_read_.msgIds.push_back("msgid2"); ::AliIMMsg::SMsgMetaSeq keys; ::AliIMMsg::MsgMeta key_one; keys.push_back(key_one); keys.push_back(key_one); MOCKER(&GetWwMsgInfoAndPutToVector) .stubs() .with(any(), outBound(keys)) .will(returnValue(0)) .then(returnValue(0)); ::AliIMMsg::SBinaryMsgEx2Seq ans; ::AliIMMsg::BinaryMsgEx2 ans_one; ans_one.readFlag = 1; ans.push_back(ans_one); ans.push_back(ans_one); IceProxyClientMock kIceProxyClientMock; IceProxyClientMock::swap(&kIceProxyClientMock); EXPECT_CALL(kIceProxyClientMock, GetMsgInfo(::testing::_, ::testing::_)) .Times(1) .WillOnce(DoAll(SetArgReferee<1>(ans), Return(0))); boost::shared_ptr<BCPResult<void> > result = paas2ww_msg_read_event_mock_->ConcretVerify(); ASSERT_TRUE(result->success == true && result->code == RECONCILIATION_SUCCESS); } } // namespace WWS
相关文章推荐
- C++雾中风景番外篇2:Gtest 与 Gmock,聊聊C++的单元测试
- C++中static的用法总结
- C++ const 总结
- 玩转Google开源C++单元测试框架Google Test系列(gtest)之一 - 初识gtest
- C++各种容器特点总结
- c++的一点小总结
- c/c++中内存区域划分大总结
- C++技术问题总结-第8篇 STL内存池是怎么实现的
- c++中const与指针总结
- C++技术问题总结map、vector、list、deque各自的使用场合
- C++知识点总结(二)
- Lua和C++交互总结(很详细)
- C++ int,char,string,CString类型转换(整理总结)
- 关于C++使用中总结的一些东西(第三章)
- C++之namespace和::使用总结
- 学习C++的第一篇小总结
- 【C++】几大函数总结
- Effective C++ 总结1 从C转向C++(条款1 - 4)
- C和C++里面常见错误和异常出现怎么解决总结(不断更新)
- c/c++下时间函数总结