该文章介绍应用程序打桩操作(即将应用发送数据的时候,进行MOCK打桩,不在进行后端消息的发送,而是直接在mock处返回回调)对发送数据的send层修改。
作用:应用完全与后台分割,不在依赖后台的返回,而是直接返回成功。案例1:测试应用代码覆盖率时不依赖后端环境,直接使用gtest进行测试即可。案例2:压测应用接口最大TPS量。等等
修改:
class SendDataMock
{
public:
类的初始化
SendDataMock(CTcpClientMock* client);
void init();
public:
// 调用消息的统一入口
void operator() (structDate& sdate); // Function call operator
public:
// 回调函数
void OnLogin(const structDate& sdate)
public:
// 调用函数
void SendToData(STRUCT_TYPE1 sType1, STRUCT_TYPE2 sType2, void* pData);
private:
// 全局map,用于存放回调函数指针, key是消息类型
std::map<RN_INT64, std:function< void (const structDate& data)>> m_mapFun;
CTcpClientMock* m_client = nullptr;
};
仿函数
此仿函数又称为函数对象,是一种能够行使函数功能的类,该类重载了operator()运算符,调用仿函数的时候实际上就是通过类对象调用重载后的operator操作符,重载operator()和重载普通的函数效果相同,当参数类型不同时会执行不同的代码逻辑。
mock层函数的实现:
SendDataMock::SendDataMock(CTcpClientMock* client)
:m_client(client)
{
Init();
}
// 仿函数
void SendDataMock::operator() (structDate& sdate)
{
auto it = m_mapFun.find(MakeInt64(sdate.Type1, sdate.Type2 ));
if(it != m_mapFun .end())
{
// 调用回调函数
(*it).second(sdate);
}
else
{
cout<<"warn: sdate is need check"<<endl;
}
if(sdate)
{
free(sdate)
}
}
// 初始化回调函数指针,入map
void SendDataMock::init()
{
m_mapFun(MakeInt64 (STRUCT_TYPE1::LOGIN, STRUCT_TYPE2::ERROR_TYPE)] = std::bind(SendDataMock::OnLogin, this, std::placeholders::_1):
}
// 回调函数
void SendDataMock::OnLogin(const structDate& sdate)
{
// 组装消息返回
Logon* pLogon= (Logon *)malloc(sizeof(Logon));
memset(Logon,0,sizeof(*Logon));
... // 消息体返回
SendToData(STRUCT_TYPE1::ERROR_TYPE, STRUCT_TYPE2::ON_RSP_LOGIN, (void*) pLogon);
}
void SendDataMock::SendToData(STRUCT_TYPE1 sType1, STRUCT_TYPE2 sType2, void* pData)
{
msgData msgDt;
msgDt.Type1 = sType1;
msgDt.Type2 = sType2;
msgDt.pData = pData;
m_client->SendMessage(msgDt);
}
SendDataMock仿函数统一接收数据(原始发送给下层应用的消息),通过map中存放的函数指针,调用对应的函数直接返回(不在发往下层)
//合成一个64为的整数,用作m mapMockFun的key
RN_INT64 MakeInt64(STRUCT_TYPE1 sType1, STRUCT_TYPE2 sType2)
{
RN_INT64 1lIndex= sType1;
llIndex <<= 32;
llIndex += sType2;
return llIndex;
}
一个消息中包含多个消息类型,将消息类型合并为一个唯一的key
CTcpClientMock 应用作为服务端接收到数据处理的类
m_client->SendMessage 数据塞入线程队列的统一接入入口