简体   繁体   中英

How do I unit test and check the contents of a vector object of a custom struct using google mock?

If the structure is

struct Point{
double x;
double y;
};

and the output of a function is vector<Point> and has a size of 10, how do I write a Google Test or Google Mock(I think this is more suitable for this) to verify the contents of the vector? I can write the expected output in a Raw string.

To start of: it's fine to just write you assertions by hand, checking the size and the content element by element:

std::vector<Point> MethodReturningVector();

TEST(MethodReturningVectorTest, CheckSizeAndFirstElementTest) {
    const auto result = MethodReturningVector();

    ASSERT_EQ(10, result.size());
    ASSERT_NEAR(42.f, result[0].x, 0.001f);
    ASSERT_NEAR(3.141592.f, result[0].y, 0.001f);
}

once you write a lot of different test you'll see a common pattern of the assertions and then you can refactor your tests and it all will fall in place naturally.

But as you mentioned GMock, indeed there are some GMock techniques that you can use. There are in-built matchers to match STL-like arrays (I say STL-like because it is only required that begin and end), eg ElementsAre ( ElementsAreArray also exists). However, they require that the elements inside the array can be compared. This in turn requires that operator== is defined for your type (rarely is) because the default Eq matcher is using it. You can define your own matchers for custom types using another in-built matchers like AllOf (aggregator of matchers) and Field (matching given field of a struct). The matchers can get combined. For full picture see ( working example ):

struct Point{
double x;
double y;
};

std::vector<Point> MethodReturningVector() {
    std::vector<Point> result(3);
    result[0] = Point{42.f, 3.141592f};
    return result;
}

MATCHER_P(Near, expected, "...") {
    constexpr auto allowed_diff = 0.001f;  // allow small diference
    if (!(expected - arg <= allowed_diff && arg <= expected + allowed_diff)) {
        *result_listener << "expected: " << expected << ", actual: " << arg;
        return false;
    }
    return true;
}

auto MatchPoint(Point p) {
    return testing::AllOf(testing::Field(&Point::x, Near(p.x)), 
                          testing::Field(&Point::y, Near(p.y)));
}

TEST(MethodReturningVectorTest, TestOneElement)
{
    const auto result = MethodReturningVector();
    
    ASSERT_EQ(result.size(), 3);
    ASSERT_THAT(result[0], MatchPoint(Point{42.f, 3.1415}));
}

TEST(MethodReturningVectorTest, TestWholeArray)
{
    const auto result = MethodReturningVector();
    
    ASSERT_THAT(result, testing::ElementsAre(
        MatchPoint(Point{42.f, 3.1415f}), 
        MatchPoint(Point{0.f, 0.f}), 
        MatchPoint(Point{0.f, 0.f})));
}

I strongly suggest you start with GTest/GMock cookbook etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM