英文:
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 <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();
}
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, "")
{
return ExplainMatchResult(subMatcher, std::make_tuple(arg, size), result_listener);
}
这是代码片段中的一个自定义匹配器。它将指针参数转换为指针和大小的元组,以便其他匹配器能够像使用C++20中的std::span
一样处理它。
#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);
}
这是代码片段中的另一个自定义匹配器的使用示例。
请注意,代码部分已经包括在您的请求中,不需要额外的翻译。
英文:
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, "")
{
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 <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);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论