struct obj
{
int a;
string str;
string str2;
bool operator==(const obj& o) const
{
if(a == o.a && str == o.str && str2 == o.str2) return true;
return false;
}
}
Then in a function in a class, it is using struct object as input parameters:
bool functionNeedsToBeMocked(obj& input)
{
//do something
}
Now what I want to do is,
EXPECT_CALL(*mockedPointer, functionNeedsToBeMocked( /* if input.a == 1 && input.str == "test" && input.str2.contains("first")*/ )).Times(1).WillOnce(Return(true));
And the input value is
inputFirst.a = 1;
inputFirst.str = "test";
inputFirst.str2 = "something first";
I expect the inputFirst can be matched to my EXPECT_CALL.
How could I using EXPECT_CALL matcher to do that ?
I did see
EXPECT_CALL(foo, DoThat(Not(HasSubstr("blah")),
NULL));
on gmock cookbook, but I don't know how to do HasSubStr for a struct parameter.
You can implement your own matcher for the obj
struct.
When you type:
EXPECT_CALL(*mockedPointer, functionNeedsToBeMocked(some_obj)).Times(1).WillOnce(Return(true));
then gmock is using the default matcher, Eq
, using some_obj
as its expected argument and the actual functionNeedsToBeMocked
argument as arg
in the matcher. Eq
matcher will by default call bool operator==
for the expected and actual objects:
EXPECT_CALL(*mockedPointer, functionNeedsToBeMocked(Eq(some_obj))).Times(1).WillOnce(Return(true));
However, as you don't want to use the bool operator==
, you can write a custom matcher (removing Times(1)
as it is the default one as well):
// arg is passed to the matcher implicitly
// arg is the actual argument that the function was called with
MATCHER_P3(CustomObjMatcher, a, str, str2, "") {
return arg.a == a and arg.str == str and (arg.str2.find(str2) != std::string::npos);
}
[...]
EXPECT_CALL(*mockedPointer, functionNeedsToBeMocked(CustomObjMatcher(1, "test", "first"))).WillOnce(Return(true));
There's a possibility to compose a custom matcher usig Field
matchers and in-built matchers as HasString
but let's 'leave it as an excercise to the reader' :P
Update: Full blown code with Field
matchers:
struct obj {
int a;
std::string str;
std::string str2;
};
struct Mock {
MOCK_METHOD(bool, functionNeedsToBeMocked, (obj&));
};
// creates a matcher for `struct obj` that matches field-by-field
auto Match(int expected_a, std::string expected_str1, std::string expected_substr2) {
return testing::AllOf(
testing::Field(&obj::a, expected_a),
testing::Field(&obj::str, expected_str1),
testing::Field(&obj::str2, testing::HasSubstr(expected_substr2))
);
}
TEST(MyTest, test) {
Mock mock{};
obj inputFirst;
inputFirst.a = 1;
inputFirst.str = "test";
inputFirst.str2 = "something first";
EXPECT_CALL(mock, functionNeedsToBeMocked(Match(1, "test", "first"))).Times(1).WillOnce(Return(true));
mock.functionNeedsToBeMocked(inputFirst);
}