英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论