C ++ Google Mock SaveArg:如何保存指针参数

时间:2014-09-17 12:00:17

标签: c++ googlemock

我很难保存我的模拟接收的指针参数。

#define SIZE_OF_DATA

typedef struct {
    uint32_t someValue1;
    uint16_t someValue2;
    // other values here
} LargeStruct;


class SomeClass {
public:
    // assume sendData is a generic function where data is actually pointer to a LargeStruct
    void sendData(const uint8_t* data, const uint16_t size);
}

class MockClass : public SomeClass {
public:
    MOCK_METHOD2(sendData, void(const uint8_t*, const uint16_t));
};

我想将第一个参数保存到sendData(指针)并查看它指向的数据(它指向一个大结构,所以我不想按值复制):

TEST(SomeFixture, sendData_checkSentDataIsValid) {
   MockClass mock;

  const uint8_t *pData;
  EXPECT_CALL(mock, sendData(_, SIZE_OF_DATA)).WillOnce(SaveArg<0>(&pData));

  // do something here that calls sendData()

  // hopefully data should point to the same data that was passed in to the method
  LargeStruct *ls = (LargeStruct *)pData;

  // now verify that the data is ok...
  // some expectations here
  EXPECT_EQ(SOMEVALUEIWANT, ls->someValue1); 

}

然而,pData指向的数据是错误的 - 我想我似乎是将指针值保存到结构中,而不是保存指针。

我认为问题在于我传递给SaveArg的变量,但我似乎无法在编译的版本中得到它并给出正确的答案。有什么指示吗?

2 个答案:

答案 0 :(得分:7)

我遇到了同样的情况,在我的情况下,我必须确保传递到sendData()函数的等价物的指针没有指向堆栈上的自动变量。否则,在您访问指针时,内容将会更改。我发现这不太有帮助,所以我决定像这样定义SaveArg的定制替代品:

ACTION_TEMPLATE(SaveSomeValue1,
                HAS_1_TEMPLATE_PARAMS(int, k),
                AND_1_VALUE_PARAMS(pointer))
{
    const void * data = ::std::tr1::get<k>(args);
    const LargeStruct* ls = (const LargeStruct *)data;
    *pointer = ls->someValue1;
}

然后您可以像这样使用它:

uint32_t someValue1;
EXPECT_CALL(mock, sendData(_, SIZE_OF_DATA))
    .WillOnce(SaveSomeValue1<0>(&someValue1));
//...
EXPECT_EQ(SOMEVALUEIWANT, someValue1);

答案 1 :(得分:1)

您可以创建一个void指针作为缓冲区并将参数保存在该缓冲区中。之后,您应该将缓冲区转换为大型结构。

 TEST(SomeFixture, sendData_checkSentDataIsValid) {
  MockClass mock;
  LargeStruct *ls;
  void *buffer;

  EXPECT_CALL(mock, sendData(_, SIZE_OF_DATA))
             .WillOnce(SaveArg<0>(&buffer));

 // do something here that calls sendData()

  ls = static_cast<LargeStruct  *>(buffer);

  EXPECT_EQ(SOMEVALUEIWANT, ls->someValue1); 

}