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

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

c++ googlemock: How can you verify all the elements of an array pointer passed to a mocked function?

问题

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 not able to fetch the elements 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};
  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();
}

How can I modify this test so I am able to verify all three elements of the array that was passed to fortran_interface_test_func_pointerargs? I can't just compare them directly because I need to store the array that was passed in testfunc_pointer first, which is not possible with the current implementation using SetArrayArgument

英文:

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 not able to fetch the elements of the array:

#include &lt;iostream&gt;
#include &lt;gtest/gtest.h&gt;
#include &lt;gmock/gmock.h&gt;
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-&gt;fortran_interface_test_func_pointerargs(&amp;testscalar, &amp;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&lt;0&gt;(&amp;passed_scalar),
        testing::SetArrayArgument&lt;1&gt;(passed_array, passed_array + 3)
    ));
  testfunc_pointer(&amp;mock_func_interface);
  std::cout &lt;&lt; passed_scalar &lt;&lt; std::endl; // prints 123
  std::cout &lt;&lt; passed_array[0] &lt;&lt; &quot; &quot; &lt;&lt; passed_array[1] &lt;&lt; &quot; &quot; &lt;&lt; passed_array[2] &lt;&lt; std::endl; // prints 0 0 0
}

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

How can I modify this test so I am able to verify all three elements of the array that was passed to fortran_interface_test_func_pointerargs? I can't just compare them directly because I need to store the array that was passed in testfunc_pointer first, which is not possible with the current implementation using SetArrayArgument

答案1

得分: 1

以下是代码部分的翻译:

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

这是代码片段中的一个自定义匹配器。它将指针参数转换为指针和大小的元组,以便其他匹配器能够像使用C++20中的std::span一样处理它。

#include &lt;gmock/gmock.h&gt;
#include &lt;gtest/gtest.h&gt;

using ::testing::ElementsAre;

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

这是代码片段中的另一个自定义匹配器的使用示例。

请注意,代码部分已经包括在您的请求中,不需要额外的翻译。

英文:

Ok I can't find anything in google toolbox which could address this issue.

But this can be solved by providing own matcher:

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

This matcher allows convert pointer argument to tuple of pointer and size which other matchers are treating like std::span (available since C++20).

So test can be tweaked this way (modification of my MCVE from comment):

#include &lt;gmock/gmock.h&gt;
#include &lt;gtest/gtest.h&gt;

using ::testing::ElementsAre;

MATCHER_P2(ArrayPointee, size, subMatcher, &quot;&quot;)
{
    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&amp; 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);
}

huangapple
  • 本文由 发表于 2023年4月1日 00:22:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/75900743.html
匿名

发表评论

匿名网友

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

确定