你可以如何读取通过Google Mock模拟的方法传递的数组指针的内容?

huangapple go评论65阅读模式
英文:

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([&amp;](int* scalar, int* array){
    passed_scalar = *scalar;
    for(int i = 0; i &lt; 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.

huangapple
  • 本文由 发表于 2023年3月31日 17:50:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/75897097.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定