您的位置:首页 > 编程语言 > C语言/C++

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

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: