如何读取传递给使用 googlemock 模拟的方法的数组指针的内容?

问题描述 投票:0回答:1

我将一个指向数组的指针传递给一个函数,我正在用 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

c++ unit-testing googletest googlemock
1个回答
1
投票

我认为没有自定义 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 来满足需求。

© www.soinside.com 2019 - 2024. All rights reserved.