C++ 当SETARG裁判通过矢量时,未完成gtest中的期望值 #包括 #包括 枚举类信息状态:uint8\t { 关=0, ON=1, }; 类MyInfo { 公众: MyInfo(){}; MyInfo(constmyinfo&){}; MyInfo&运算符=(常量MyInfo&){} MOCK_方法0(getState、InfoState(void)); }; 类服务客户端 { 公众: MOCK_方法1(getInfo,bool(std::vector和myInfoList)); }; 类别MyClassA { 公众: ServiceClient m_ServiceClient; void updateStatus() { 向量myInfoList; if(m_serviceClient.getInfo(myInfoList)) { 用于(自动和信息:myInfoList) { if(InfoState::ON==info.getState()) { //通知观察员(真实); 打破 } } } } }; 测试(infoTest,test1) { MyClassA testObj; std::向量MyTestInfo列表(1); 预期_调用(myTestInfo[0],getState()).WillOnce(::testing::Return(InfoState::ON)); EXPECT_调用(testObj.m_serviceClient,getInfo(::测试::)) .WillOnce(::testing::DoAll(::testing::setargreference
作为注释,主要问题是一个复制构造函数。我不是C++ 当SETARG裁判通过矢量时,未完成gtest中的期望值 #包括 #包括 枚举类信息状态:uint8\t { 关=0, ON=1, }; 类MyInfo { 公众: MyInfo(){}; MyInfo(constmyinfo&){}; MyInfo&运算符=(常量MyInfo&){} MOCK_方法0(getState、InfoState(void)); }; 类服务客户端 { 公众: MOCK_方法1(getInfo,bool(std::vector和myInfoList)); }; 类别MyClassA { 公众: ServiceClient m_ServiceClient; void updateStatus() { 向量myInfoList; if(m_serviceClient.getInfo(myInfoList)) { 用于(自动和信息:myInfoList) { if(InfoState::ON==info.getState()) { //通知观察员(真实); 打破 } } } } }; 测试(infoTest,test1) { MyClassA testObj; std::向量MyTestInfo列表(1); 预期_调用(myTestInfo[0],getState()).WillOnce(::testing::Return(InfoState::ON)); EXPECT_调用(testObj.m_serviceClient,getInfo(::测试::)) .WillOnce(::testing::DoAll(::testing::setargreference,c++,vector,googletest,googlemock,C++,Vector,Googletest,Googlemock,作为注释,主要问题是一个复制构造函数。我不是谷歌测试专家,但我找到了解决您问题的方法 根据GMock,我发现模拟对象无法复制-这是googletest实现者的设计原则和决定。早在2009年 因此,如果不在模拟对象内部定义复制构造函数,它将被删除()。下面是错误代码 #include <gtest/gtest.h> #include <gmock/gmock.h> enum class InfoState : uint8_t { OFF = 0,
谷歌测试
专家,但我找到了解决您问题的方法
根据GMock
,我发现模拟对象无法复制-这是googletest
实现者的设计原则和决定。早在2009年
因此,如果不在模拟对象内部定义复制构造函数,它将被删除()。下面是错误代码
#include <gtest/gtest.h>
#include <gmock/gmock.h>
enum class InfoState : uint8_t
{
OFF = 0,
ON = 1,
};
class MyInfo
{
public:
MyInfo(){};
MyInfo(const MyInfo&){};
MyInfo& operator=(const MyInfo&){}
MOCK_METHOD0(getState, InfoState(void));
};
class ServiceClient
{
public:
MOCK_METHOD1(getInfo, bool(std::vector<MyInfo> &myInfoList));
};
class MyClassA
{
public:
ServiceClient m_serviceClient;
void updateStatus()
{
std::vector<MyInfo> myInfoList;
if (m_serviceClient.getInfo(myInfoList))
{
for (auto& info: myInfoList)
{
if (InfoState::ON == info.getState())
{
//notifyObservers(true);
break;
}
}
}
}
};
TEST(infoTest, test1)
{
MyClassA testObj;
std::vector<MyInfo> myTestInfoList(1);
EXPECT_CALL(myTestInfoList[0], getState()).WillOnce(::testing::Return(InfoState::ON));
EXPECT_CALL(testObj.m_serviceClient, getInfo(::testing::_))
.WillOnce(::testing::DoAll(::testing::SetArgReferee<0(myTestInfoList),::testing::Return(true)));
testObj.updateStatus();
}
然而,这里的主要问题实际上是复制构造函数的实际需要,这是由两个因素造成的:
EXPECT\u CALL
和其他GMock基本功能都不会被复制!这正是您面临的问题。因此,您创建了一个自定义的复制构造函数,并且所有的GMock功能都消失了假装这个构造函数是空的——它无论如何都不会开箱即用std::vector
,它要求您(在本用例中)的类型符合概念。因此,这将不起作用EXPECT\u CALL
正在使用copy而不是move语义或传递引用。尽管您显式地将该参数设置为引用(而不是副本!)setargreference(MyTestInfo列表),但还是这样做了
。此外,通过设计GMock
对象是不可复制的。对我来说,这看起来像是设计缺陷或bug,但我不是googletest
专家。我将对此做更多研究,并可能向GTest
实施者提出bug报告/问题
好的,但要找到解决方案,我们需要首先在gmockapi
中找到一个不使用副本的方法,然后使用std::vector
功能,该功能不调用副本构造函数
第一个问题将通过将EXPECT\u CALL
更改为ON\u CALL
来解决,并且为了打开调用std::vector
功能的可能性,我们还将从GMock
API使用Invoke
。
()
这是工作表
如前所述,我将尝试调查为什么GMock
EXPECT\u CALL
强制进行复制。EXPECT\u CALL
s在内部进行复制-在我看来,mytestinfo列表
是在内部复制的,因此您设置的EXPECT调用是在与updateStatus
函数中使用的对象不同的对象上设置的。
/opt/compiler-explorer/libs/googletest/release-1.10.0/googlemock/include/gmock/gmock-spec-builders.h:1483:3: note: 'FunctionMocker' has been explicitly marked deleted here
FunctionMocker(const FunctionMocker&) = delete;
MyInfo(const MyInfo&){};
TEST(infoTest, test1)
{
MyClassA testObj;
std::vector<MyInfo> myTestInfoList(1);
ON_CALL(myTestInfoList[0], getState()).WillByDefault(::testing::Invoke(
[]()
{
return InfoState::ON;
}));
ON_CALL(testObj.m_serviceClient, getInfo(::testing::_))
.WillByDefault(::testing::Invoke(
[](std::vector<MyInfo> &myInfoList)
{
return true;
}));
testObj.updateStatus();
}
ON_CALL(testObj.m_serviceClient, getInfo(::testing::_))
.WillByDefault(::testing::Invoke(
[&myTestInfoList](std::vector<MyInfo> &myInfoList)
{
std::swap(myInfoList, myTestInfoList);
return true;
}));