C++ 如何在google测试中测试多线程?

C++ 如何在google测试中测试多线程?,c++,multithreading,googletest,C++,Multithreading,Googletest,下面的测试代码创建一个服务器和一个clientsocket。然后客户端向服务器发送消息,服务器回复。就这些。但我不能编译。thread函数中的所有ASSERT\u EQ都会引发错误“错误:无效值不会被忽略,因为它应该是”。我不知道这会告诉我什么。这里有什么问题?类型是不相关的,因为ASSERT_EQ(1,1)也会引发错误 编辑在谷歌常见问题解答中找到: 问:我的编译器抱怨“void值不应该被忽略”,这是什么意思 答:您可能在不返回void的函数中使用了ASSERT_XY()。ASSERT_XY(

下面的测试代码创建一个服务器和一个clientsocket。然后客户端向服务器发送消息,服务器回复。就这些。但我不能编译。thread函数中的所有
ASSERT\u EQ
都会引发错误
“错误:无效值不会被忽略,因为它应该是”
。我不知道这会告诉我什么。这里有什么问题?类型是不相关的,因为
ASSERT_EQ(1,1)也会引发错误

编辑在谷歌常见问题解答中找到:

问:我的编译器抱怨“void值不应该被忽略”,这是什么意思

答:您可能在不返回void的函数中使用了ASSERT_XY()。ASSERT_XY()只能在void函数中使用

我该如何理解这一点

void * serverfunc(void * ptr);  
void * clientfunc(void * ptr);    

TEST(netTest, insert)
{
  pthread_t mThreadID1, mThreadID2;
  ::pthread_create(&mThreadID1, nullptr, serverfunc, nullptr);
  ::sleep(1);
  ::pthread_create(&mThreadID1, nullptr, clientfunc, nullptr);
  ::pthread_join(mThreadID1, nullptr);
  ::pthread_join(mThreadID2, nullptr);        
}

void * serverfunc(void * ptr)
{
  net::ServerSocket serv(IPV4, TCP, 55555,5);
  net::ServerSocket * conn = serv.accept();
  net::Message msg;

  conn->recvmsg(&msg);

  ASSERT_EQ(msg.size(),5);
  ASSERT_EQ(msg[0],1);
  ASSERT_EQ(msg[1],2);
  ASSERT_EQ(msg[2],3);
  ASSERT_EQ(msg[3],4);
  ASSERT_EQ(msg[4],5);

  msg = {9,8,6};
  ASSERT_EQ(msg.size(),3);
  ASSERT_EQ(msg[0],9);
  ASSERT_EQ(msg[1],8);
  ASSERT_EQ(msg[2],6);

  conn->sendmsg(msg);

  ::sleep(1);

  delete conn;
  return 0;
}

void * clientfunc(void * ptr)
{
  net::ClientSocket clie(IPV4, TCP, "localhost",55555);
  net::Message msg;

  msg = {1,2,3,4,5};
  ASSERT_EQ(msg.size(),5);
  ASSERT_EQ(msg[0],1);
  ASSERT_EQ(msg[1],2);
  ASSERT_EQ(msg[2],3);
  ASSERT_EQ(msg[3],4);
  ASSERT_EQ(msg[4],5);

  clie.sendmsg(msg);

  clie.recvmsg(&msg);

  ASSERT_EQ(msg.size(),3);
  ASSERT_EQ(msg[0],9);
  ASSERT_EQ(msg[1],8);
  ASSERT_EQ(msg[2],6);

  return 0;
}

看起来ASSERT_EQ只能在返回类型正确的函数中调用(返回void*,返回void*)

我个人不喜欢宏的过度使用,但事实就是这样。宏的问题是它混淆了代码,所以你看不出它做错了什么

所以只需编写这样一个函数,让serverfunc和clientfunc调用它

问:我的编译器抱怨“void值没有被忽略,因为它应该被忽略。” 这是什么意思

答:您可能在一个不需要的函数中使用了ASSERT_XY() 返回无效。ASSERT_XY()只能在void函数中使用

我该如何理解这一点

void * serverfunc(void * ptr);  
void * clientfunc(void * ptr);    

TEST(netTest, insert)
{
  pthread_t mThreadID1, mThreadID2;
  ::pthread_create(&mThreadID1, nullptr, serverfunc, nullptr);
  ::sleep(1);
  ::pthread_create(&mThreadID1, nullptr, clientfunc, nullptr);
  ::pthread_join(mThreadID1, nullptr);
  ::pthread_join(mThreadID2, nullptr);        
}

void * serverfunc(void * ptr)
{
  net::ServerSocket serv(IPV4, TCP, 55555,5);
  net::ServerSocket * conn = serv.accept();
  net::Message msg;

  conn->recvmsg(&msg);

  ASSERT_EQ(msg.size(),5);
  ASSERT_EQ(msg[0],1);
  ASSERT_EQ(msg[1],2);
  ASSERT_EQ(msg[2],3);
  ASSERT_EQ(msg[3],4);
  ASSERT_EQ(msg[4],5);

  msg = {9,8,6};
  ASSERT_EQ(msg.size(),3);
  ASSERT_EQ(msg[0],9);
  ASSERT_EQ(msg[1],8);
  ASSERT_EQ(msg[2],6);

  conn->sendmsg(msg);

  ::sleep(1);

  delete conn;
  return 0;
}

void * clientfunc(void * ptr)
{
  net::ClientSocket clie(IPV4, TCP, "localhost",55555);
  net::Message msg;

  msg = {1,2,3,4,5};
  ASSERT_EQ(msg.size(),5);
  ASSERT_EQ(msg[0],1);
  ASSERT_EQ(msg[1],2);
  ASSERT_EQ(msg[2],3);
  ASSERT_EQ(msg[3],4);
  ASSERT_EQ(msg[4],5);

  clie.sendmsg(msg);

  clie.recvmsg(&msg);

  ASSERT_EQ(msg.size(),3);
  ASSERT_EQ(msg[0],9);
  ASSERT_EQ(msg[1],8);
  ASSERT_EQ(msg[2],6);

  return 0;
}

您的函数不返回
void
,它们返回
void*
——也就是说,它们返回一些东西(
void*
是指向任何东西的指针),而它们不应该返回任何东西。常见问题解答说,使用ASSERT_EQ()的函数必须具有
void
返回类型。

正如建议的那样,您应该将方法的
void*
类型替换为
void
,将
return 0
替换为
return
我也有同样的问题,我找到了一个“丑陋”的解决方法:

void* your_func(void* ptr)
{
    _your_func(ptr);
    reutrn NULL;
}

void _your_func(void* ptr)
{
    ...
    ASSERT_EQ(1, 1);
    ...
}

这并不完全正确。我在其他函数中也使用ASSERT_EQ(从GTest单元测试中调用)。限制是ASSERT_EQ必须在返回void的函数中。谢谢,@TylerMcHenry有趣的是,他们设法为没有宏的其他语言制作了这些测试工具,然而,每当他们为C++实现它们时,总是充满了它们。首先,C++根本不支持反射,所以测试夹具的通用方法的唯一方法是使用宏来使用固定设备的名称并用它做令牌粘贴(例如TestIf)。另一个原因是,特别是GoGoLeST,它是在谷歌内部开发的,而谷歌C++风格指南不允许异常。所以像ASSERT_*这样的东西必须是宏才能在测试中插入return语句,这实际上是终止测试的唯一其他方法。@TylerMcHenry我想你说的是,宏可以在行失败的情况下对输入的文本进行字符串化,并执行它,这就是为什么它在单元测试中工作得很好。您可以使用EXPECT_,我认为它输出警告而不是错误