使用 gmock 保存 C 样式数组值
Save C-Style array values using gmock
我对我的一件物品有以下期望:
EXPECT_CALL(usbMock, Write(_, expectedBufferLength));
其中“_”参数是传递给 usbMock 上的 Write 函数的缓冲区。
我需要获取该缓冲区内的值,以便我可以 运行 我自己的数组比较函数(ElementsAreArray 和 ElementsAre 对我不起作用,因为我需要自定义输出消息,其中包含expected/actual数组,而且我的数组长度超过10个字节);
无论如何,我已经非常接近解决我的问题了:
byte* actualBuffer;
EXPECT_CALL(usbMock, Write(_, expectedBufferLength)).WillOnce(SaveArg<0>(&actualBuffer));
问题是这是一个集成测试,当我能够对其采取行动时,actualBuffer 指向的缓冲区已被释放。
我的问题是,如何保存 actualBuffer 的内容以供以后检查,而不是仅仅获取指向它的指针。
我遇到过几次相同的情况,我有两种可能的策略可以提供:
- 您可以定义自定义匹配器(参见
MATCHER_Px
宏)
- 您可以使用
Invoke
并在回调中执行您需要的操作
在你的情况下,这将取决于你是否知道在调用代码时会发生什么:如果你已经知道,那么你可以定义一个匹配器,在参数中接受预期的数组,否则如果你需要保存可以使用Invoke
中的回调进行深拷贝。
一些代码示例:
// Invoke
EXPECT_CALL(usbMock, Write(_, expectedBufferLength))
.WillOnce(Invoke([expectedBuffer](byte* actualBuffer, size_t length) {
// Substitute for your matching logic
for (size_t i = 0; i != length; ++i) {
EXPECT_EQ(actualBuffer[i], expectedBuffer[i]);
}
});
还有匹配器:
MATCHER_P2(ByteBufferMatcher, buffer, length, "") {
return std::equal(arg, arg + length, buffer);
}
// Usage
EXPECT_CALL(usbMock,
Write(ByteBufferMatcher(expectedBuffer, expectedLength), expectedLength));
请注意,后者使得提供自定义错误消息变得更加困难。
你可以这样做:
MATCHER_P(CompareCustomArray, expectedArray, "") {
CustomArray* customArray = std::get<0>(arg);
return ((*customArray) == (*expectedArray));
}
CustomArray actualBuffer("Expected Buffer Value");
EXPECT_CALL(usbMock, Write(CompareCustomArray(&actualBuffer),
expectedBufferLength));
这里我们创建了特定的匹配器,用于比较两个 CustomArray
和 "passes" 如果它们相等。
我对我的一件物品有以下期望:
EXPECT_CALL(usbMock, Write(_, expectedBufferLength));
其中“_”参数是传递给 usbMock 上的 Write 函数的缓冲区。
我需要获取该缓冲区内的值,以便我可以 运行 我自己的数组比较函数(ElementsAreArray 和 ElementsAre 对我不起作用,因为我需要自定义输出消息,其中包含expected/actual数组,而且我的数组长度超过10个字节);
无论如何,我已经非常接近解决我的问题了:
byte* actualBuffer;
EXPECT_CALL(usbMock, Write(_, expectedBufferLength)).WillOnce(SaveArg<0>(&actualBuffer));
问题是这是一个集成测试,当我能够对其采取行动时,actualBuffer 指向的缓冲区已被释放。
我的问题是,如何保存 actualBuffer 的内容以供以后检查,而不是仅仅获取指向它的指针。
我遇到过几次相同的情况,我有两种可能的策略可以提供:
- 您可以定义自定义匹配器(参见
MATCHER_Px
宏) - 您可以使用
Invoke
并在回调中执行您需要的操作
在你的情况下,这将取决于你是否知道在调用代码时会发生什么:如果你已经知道,那么你可以定义一个匹配器,在参数中接受预期的数组,否则如果你需要保存可以使用Invoke
中的回调进行深拷贝。
一些代码示例:
// Invoke
EXPECT_CALL(usbMock, Write(_, expectedBufferLength))
.WillOnce(Invoke([expectedBuffer](byte* actualBuffer, size_t length) {
// Substitute for your matching logic
for (size_t i = 0; i != length; ++i) {
EXPECT_EQ(actualBuffer[i], expectedBuffer[i]);
}
});
还有匹配器:
MATCHER_P2(ByteBufferMatcher, buffer, length, "") {
return std::equal(arg, arg + length, buffer);
}
// Usage
EXPECT_CALL(usbMock,
Write(ByteBufferMatcher(expectedBuffer, expectedLength), expectedLength));
请注意,后者使得提供自定义错误消息变得更加困难。
你可以这样做:
MATCHER_P(CompareCustomArray, expectedArray, "") {
CustomArray* customArray = std::get<0>(arg);
return ((*customArray) == (*expectedArray));
}
CustomArray actualBuffer("Expected Buffer Value");
EXPECT_CALL(usbMock, Write(CompareCustomArray(&actualBuffer),
expectedBufferLength));
这里我们创建了特定的匹配器,用于比较两个 CustomArray
和 "passes" 如果它们相等。