CppUTest:如何将更多数据传递给特定的模拟调用?
我开始为一些C / C ++项目使用CppUTest。 特别是嘲笑扩展听起来不错,但我目前正在努力如何以正确的方式设置模拟。 假设一个抽象网络套接字通信的低级别类。
我的第一个方法:
size_t CMockSocket::recv(void* buf, size_t len)
{
  return (size_t) mock().actualCall("recv")
      .withParameter("len", (int) len)
      .returnValue().getIntValue();
}
设定期望值:
mock().expectOneCall("recv")
    .withParameter("len", 20)
    .andReturnValue(15);
  到现在为止还挺好。  但我需要的是提供更多数据 - 在这种情况下,我想通过buf指针返回15个字节。  我试图使用.setData()和setDataObject()方法。  但它看起来像函数将数据存储在命名变量中,而不是预期的函数调用。  因此后续的调用会覆盖前面的数据,对吧? 
我目前的问题是如何将额外的返回数据传递给模拟方法? 我的第一个意见是创建一个包含返回值(size_t)和数据缓冲区的结果类。 喜欢这个:
class CRecvResults
{
public:
  size_t m_returnValue;
  void* m_buffer;
  CRecvResults(size_t returnValue, void* buffer) :
    m_returnValue(returnValue), m_buffer(buffer) {}
  ~CRecvResults() {}
};
size_t CMockSocket::recv(void* buf, size_t len)
{
  CRecvResults* pResults =
      (CRecvResults*) mock().actualCall("recv")
      .withParameter("len", (int) len)
      .returnValue().getPointerValue());
  assert(pResults != NULL);
  assert(buf != NULL);
  assert(len >= pResults->m_buffer.length());
  memcpy(buf, pResults->m_buffer.data(), pResults->m_buffer.length());
  return pResults->m_returnValue;
}
期望:
char* buffer = "some returning buffer content at least 15 chars long";
CRecvResults results(15, buffer);
mock().expectOneCall("recv")
      .withParameter("len", 20)
      .andReturnValue(&results);
问题:这是正确的方式,还是我错过了什么? 我需要缓冲区内容,因为我需要测试结果解释器。
我的第二种方法:
bool CMockSocket::send(const void* buf, size_t len)
{
  return mock().actualCall("send")
      .withParameter("len", (int) len)
      .returnValue().getIntValue();
}
设定期望值:
mock().expectOneCall("send")
    .withParameter("len", 20)
    .andReturnValue(true);
在这种情况下,我想验证buf中的输出数据,由测试中的代码生成。 因此我需要将该缓冲区内容(和长度)返回给测试函数。 喜欢这个:
class CSendResults
{
public:
  bool m_returnValue;
  char* m_buffer;
  size_t m_length;
  CSendResults(bool returnValue, char* buffer, size_t length) :
    m_returnValue(returnValue), m_buffer(buffer), m_length(length) {}
  ~CSendResults() {}
};
bool CMockSocket::send(const void* buf, size_t len)
{
  CSendResults* pResults =
      (CSendResults*) mock().actualCall("send")
      .returnValue().getPointerValue();
  assert(pResults != NULL);
  assert(buf != NULL);
  assert(pResults->m_length >= len);
  memcpy(pResults->m_buffer, buf, len);
  pResults->m_length = len;
  return pResults->m_returnValue;
}
期望:
char buffer[1024];
CSendResults results(true, buffer, sizeof(buffer);
mock().expectOneCall("send")
      .withParameter("len", 20)
      .andReturnValue(&results);
// further checks for results content...
这看起来非常丑陋,给我带来了很多开销。 我的问题再次出现:这是正确的方式,还是我错过了什么?
我的最后一个问题是:我能否完全错误地测试? 请让我知道你的经验和做法!
CppUTest中增加了一项新功能,它可以让您为模拟指定一个输出参数。 这可能是这样的:
{
    return (size_t) mock().actualCall("recv")
        .withOutputParameter("buf", buf)
        .withParameter("len", (int) len)
        .returnUnsignedLongIntValueOrDefault(0);
}
期望可能如下所示:
char buffer[] = "blabla";
mock().expectOneCall("recv")
    .withOutputParameterReturning("buf", buffer, sizeof(buffer))
    .withParameter("len", sizeof(buffer))
    .andReturnValue(sizeof(buffer));
  buffer的内容将通过输出参数复制到模拟的调用者。  所以不再需要丑陋的解决方法。 
我正在使用以下丑陋的解决方法。 我为返回值定义了一个结构类型,并在我的假函数中添加了我需要的额外数据。 我分配并填充一个实例,我调用expectOneCall()并使用“.andReturnValue()”传递它。 在假的功能我得到我的数据“...的returnValue()。getPointerValue()”,然后我设定的返回值struct-> RC,和处理我的附加数据(复制/把它比作缓冲)。 在退出假功能之前,结构被释放。
这样,所需的附加数据就会绑定到函数调用的参数列表。
Foltos
链接地址: http://www.djcxy.com/p/73205.html上一篇: CppUTest: how to pass more data to a specific mock call?
下一篇: trying to copy a char pointer using memcpy, getting an error
