英文:
How can you read the contents of an array pointer passed to a method mocked with googlemock?
问题
I am passing a pointer to an array to a function, which I am mocking with googlemock. I would like to verify the contents of the arguments, which works fine for scalars, but I am only able to fetch the first element of the array:
我正在将指向数组的指针传递给一个函数,我正在使用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();
}
How can I modify this test so I am able to verify all three array elements?
我如何修改这个测试以便能够验证所有三个数组元素?
I also tried using the SetArrayArgument functionality as defined in the 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
}
But this doesn't store anything and passed_array remains unmodified after the function call. How can I verify the arguments passed to my function, without modifying the testfunc_pointer function?
但这不会存储任何内容,并且在函数调用后passed_array保持不变。如何验证传递给我的函数的参数,而不修改testfunc_pointer函数?
英文:
I am passing a pointer to an array to a function, which I am mocking with googlemock. I would like to verify the contents of the arguments, which works fine for scalars, but I am only able to fetch the first element of the array:
#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();
}
How can I modify this test so I am able to verify all three array elements?
I also tried using the SetArrayArgument functionality as defined in the documentation:
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
}
But this doesn't store anything and passed_array remains unmodified after the function call. How can I verify the arguments passed to my function, without modifying the testfunc_pointer function?
答案1
得分: 1
I don't think it's possible without a custom 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 the first argument, but that requires some more work using With() to separate arguments
You can't use SaveArg or SaveArgPointee, because that would only save a pointer to the array and the array is dead as soon as testfunc_pointer returns - you have to copy the contents while still inside mock call.
And Set* family of Actions set the argument passed to mock, not the argument passed to expectation. You could notice a difference in testfunc_pointer after the call to mock, but it won't change your local variables in the test.
That leaves us with having to write a custom lambda/Action to fit the needs.
英文:
I don't think it's possible without a custom 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
You can't use SaveArg or SaveArgPointee, because that would only save a pointer to the array and the array is dead as soon as testfunc_pointer returns - you have to copy the contents while still inside mock call.
And Set* family of Actions set the argument passed to mock, not the argument passed to expectation. You could notice a difference in testfunc_pointer after the call to mock, but it won't change your local variables in test.
That leaves us with having to write a custom lambda/Action to fit the needs.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论