我将一个指向数组的指针传递给一个函数,我正在用 googlemock 模拟它。我想验证参数的内容,这适用于标量,但我只能获取数组的第一个元素:
#include <iostream>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
class InterfaceTest : public ::testing::Test {};
class MockFortranFuncInterfacePointerArgs {
public:
MOCK_METHOD(void, fortran_interface_test_func_pointerargs, (int*, int*));
};
void testfunc_pointer(MockFortranFuncInterfacePointerArgs* func_interface) {
int testscalar = 123;
int testarray[3] = {1, 2, 3};
func_interface->fortran_interface_test_func_pointerargs(&testscalar, &testarray[0]);
}
TEST_F(InterfaceTest, TestFuncInterfacePointerArgs) {
MockFortranFuncInterfacePointerArgs mock_func_interface;
int passed_scalar = 0;
int passed_array[3] = {0, 0, 0};
// int passed_array = 0;
EXPECT_CALL(mock_func_interface, fortran_interface_test_func_pointerargs(testing::_, testing::_))
.WillOnce(testing::DoAll(
testing::SaveArgPointee<0>(&passed_scalar),
testing::SaveArgPointee<1>(passed_array)
));
testfunc_pointer(&mock_func_interface);
std::cout << passed_scalar << std::endl; // prints 123
std::cout << passed_array[0] << " " << passed_array[1] << " " << passed_array[2] << std::endl; // prints 1 0 0
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
我如何修改这个测试,以便我能够验证所有三个数组元素? 我还尝试使用
documentation中定义的
SetArrayArgument
功能:
TEST_F(InterfaceTest, TestFuncInterfacePointerArgs) {
MockFortranFuncInterfacePointerArgs mock_func_interface;
int passed_scalar = 0;
int passed_array[3] = {0, 0, 0};
// int passed_array = 0;
EXPECT_CALL(mock_func_interface, fortran_interface_test_func_pointerargs(testing::_, testing::_))
.WillOnce(testing::DoAll(
testing::SaveArgPointee<0>(&passed_scalar),
testing::SetArrayArgument<1>(passed_array, passed_array + 3)
));
testfunc_pointer(&mock_func_interface);
std::cout << passed_scalar << std::endl; // prints 123
std::cout << passed_array[0] << " " << passed_array[1] << " " << passed_array[2] << std::endl; // prints 0 0 0
}
但这不会存储任何内容,
passed_array
在函数调用后保持不变。如何在不修改 testfunc_pointer
函数的情况下验证传递给我的函数的参数?
编辑:
我想验证传递给函数的值,而不是修改后的结果。我试着做
int expected_array[3] = {1, 2, 3};
EXPECT_CALL(mock_func_interface, fortran_interface_test_func_pointerargs(
testing::Pointee(123),
testing::ElementsAreArray(expected_array, 3)
));
但不幸的是,这会导致类型错误
testing::internal::ElementsAreMatcherImpl<int* const&>::StlContainer’ {aka ‘int*’} is not a class, struct, or union type
我认为没有自定义 lambda/Action 是不可能的。
EXPECT_CALL(mock_func_interface, fortran_interface_test_func_pointerargs(testing::_, testing::_))
.WillOnce(testing::Invoke([&](int* scalar, int* array){
passed_scalar = *scalar;
for(int i = 0; i < 3; ++i) {
passed_array[i] = array[i];
}
}));
//you could still use SaveArgPointee for first argument, but that requires some more work using With() to separate arguments
您不能使用
SaveArg
或 SaveArgPointee
,因为那样只会保存指向数组的指针,并且一旦 testfunc_pointer
返回,数组就死了 - 您必须在仍在模拟调用中时复制内容。Set*
系列 Actions 设置传递给 mock 的参数,而不是传递给 expectation 的参数。在调用 mock 之后,您可能会注意到 testfunc_pointer
的不同,但它不会更改测试中的局部变量。
这让我们不得不编写自定义 lambda/Action 来满足需求。