Использование сравнения gtest с плавающей запятой в Matcher

Мне нравится писать сопоставитель для структуры, которая содержит некоторые значения с плавающей запятой:

struct Point3D
{
float x;
float y;
float z;
}

class Interface
{
virtual void SetPoint(Point3D point) = 0;
}

class MockInterface:
    public Interface
{
   MOCK_METHOD1(SetPoint, void(Point3D point));
}

MATCHER_P(Point3DEq, point, "Comparison of a Point3D")
{
   return point.x == arg.x && point.y == arg.y && point.z == arg.z;
}

TEST(Point3DComparison, TestIfPoint3DAreEqual)
{
   MockInterface interfaceFake;
   Point setPoint = { 1.0, 1.0, 1.0 }
   EXPECT_CALL(interfaceFake, SetPoint(Point3DEq(setPoint)).WillOnce(Return());
}

Мне не нравится этот Matcher, потому что он не уважает хорошее сравнение с плавающей запятой. Я хотел бы написать Matcher с использованием плавающего сравнения gmock или gtest. Это должно выглядеть похоже на это.

MATCHER_P(Point3DEq, point, "Comparison of a Point3D")
{
   return EXPECT_THAT(point.x, FloatEq(arg.x) && EXPECT_THAT(point.y, FloatEq(arg.y) && EXPECT_THAT(point.z, FloatEq(arg.z);
}

Проблема в том, что EXPECT_THAT не возвращает никакого логического значения. Есть ли хороший чистый способ сделать это, используя функциональность gmock и gtest?


person PeterNL    schedule 26.06.2017    source источник


Ответы (1)


хороший способ - забыть о MATCHER_P...

Используйте ::testing::AllOf и используйте правильный сопоставители из gmock - как уже упоминалось FloatEq/DoubleEq — см.:

auto Point3DEq(Point3D const& p_expected)
{
    using namespace testing;
    return AllOf(Field(&Point3D::x, DoubleEq(p_expected.x)),
                 Field(&Point3D::y, DoubleEq(p_expected.y)),
                 Field(&Point3D::z, DoubleEq(p_expected.z)));
}
person PiotrNycz    schedule 28.06.2017
comment
Можете ли вы объяснить, как это работает на примере. Я не могу использовать эту функцию как Matcher. - person PeterNL; 06.07.2017
comment
@PeterNL используется точно так же, как это было бы определено MATCHER_P - просто EXPECT_CALL(interfaceFake, SetPoint(Point3DEq(setPoint)); - person PiotrNycz; 06.07.2017