GTEST matcher to compare vectors of given struct

83 views Asked by At

So I have this actual and expected vectors of data of defined simple struct (few fields).

I found matcher UnorderedElementsAreArray() that works "on" actual values and gets expected vector as argument to be compared with.

Less important details: array_expected is calculated in test, array_under_test is the one stored using SaveArg<> on mock's expect call.

I cannot add operator==() to that Struct definition but that's what compiler wants (to compare vector's elements).

I was trying to develop some chain of matchers, so initially I'm calling:

EXPECT_THAT(array_under_test, UnorderedElementsAreArray(array_expected));

to call mentioned gtest's matcher to deal with array/vectors but I wanted to provide my custom matcher that compares "arg" with provided "expected" elements and returns true/false (as matcher should) whenever I know the objects are equal (only few fields really matter).

I don't know how to chain UnorderedElementsAreArray with MyMatcher

MATCHER_P(MyMatcher, expected, "") {
  return arg.field1 == expected.field1;
}

Tried few things, didn't work. Don't want to flood you with bad examples that chatgpt generated :-)

1

There are 1 answers

0
Marek R On

I think you should use this approach:

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

struct CustomStruct {
    int field1;
    double field2;
    char field3;
};

void PrintTo(const CustomStruct& data, std::ostream* out)
{
    *out << '{' << data.field1 << ',' << data.field2 <<',' << data.field3 << '}';
}

MATCHER_P(InContainerField, field, "") {
    return ExplainMatchResult(testing::Field(field, std::get<1>(arg)),
                              std::get<0>(arg),
                              result_listener);
}

TEST(SomeFunctionalityTest, UsePointsWise) {
    std::vector<CustomStruct> array_under_test{ {1, 1.0, 'a'}, {2, 2.0, 'b'}};

    using testing::UnorderedPointwise;
    EXPECT_THAT(array_under_test, UnorderedPointwise(InContainerField(&CustomStruct::field1), {2, 1}));

    // failure demo
    EXPECT_THAT(array_under_test, UnorderedPointwise(InContainerField(&CustomStruct::field1), {1, 3}));
}

https://godbolt.org/z/qnGnnfqPr

But you should come up with better matcher name. This InContainerField name is bad.

Demo from old version of answer: https://godbolt.org/z/GabKdvo4K