c++ googlemock:如何验证传递给模拟函数的数组指针的所有元素?

bzzcjhmw  于 2023-04-01  发布在  Go
关注(0)|答案(1)|浏览(106)

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

int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

如何修改此测试,以便能够验证传递给fortran_interface_test_func_pointerargs的数组的所有三个元素?我不能直接比较它们,因为我需要首先存储传递给testfunc_pointer的数组,而当前使用SetArrayArgument的实现不可能做到这一点

dddzy1tm

dddzy1tm1#

好吧,我在谷歌工具箱里找不到任何可以解决这个问题的东西。
但这可以通过提供自己的matcher来解决:

MATCHER_P2(ArrayPointee, size, subMatcher, "")
{
    return ExplainMatchResult(subMatcher, std::make_tuple(arg, size), result_listener);
}

这个匹配器允许将指针参数转换为其他匹配器处理的指针和大小的元组,如std::span(自C++20起可用)。
因此,测试可以这样调整(修改我的MCVE从评论):

#include <gmock/gmock.h>
#include <gtest/gtest.h>

using ::testing::ElementsAre;

MATCHER_P2(ArrayPointee, size, subMatcher, "")
{
    return ExplainMatchResult(subMatcher, std::make_tuple(arg, size), result_listener);
}

class IFoo {
public:
    virtual void foo(int*) = 0;
};

class MockFoo : public IFoo {
public:
    MOCK_METHOD(void, foo, (int*), ());
};

void UseFoo(IFoo& foo)
{
    int arr[] { 3, 5, 7 };
    foo.foo(arr);
}

TEST(TestFoo, fooIsCalledWithProperArray)
{
    MockFoo mock;
    EXPECT_CALL(mock, foo(ArrayPointee(3, ElementsAre(3, 5, 7))));
    UseFoo(mock);
}

相关问题