Comparison of arrays in google test?

Viewed 119367

I am looking to compare two arrays in google test. In UnitTest++ this is done through CHECK_ARRAY_EQUAL. How do you do it in google test?

10 Answers

I ran into a similar problem with comparing arrays in google test.

Since I needed comparison with basic void* and char* (for low-level code testing), I don't think either Google Mock (which I'm also using in the project) or Seth's great macro could help me in the particular situation. I wrote the following macro:

#define EXPECT_ARRAY_EQ(TARTYPE, reference, actual, element_count) \
    {\
    TARTYPE* reference_ = static_cast<TARTYPE *> (reference); \
    TARTYPE* actual_ = static_cast<TARTYPE *> (actual); \
    for(int cmp_i = 0; cmp_i < element_count; cmp_i++ ){\
      EXPECT_EQ(reference_[cmp_i], actual_[cmp_i]);\
    }\
    }

The casts are there to make the macro usable when comparing void* to other stuff:

  void* retrieved = ptr->getData();
  EXPECT_EQ(6, ptr->getSize());
  EXPECT_ARRAY_EQ(char, "data53", retrieved, 6)

Tobias in the comments suggested casting void* to char* and using EXPECT_STREQ, a macro I somehow missed before - which looks like a better alternative.

With today's version you just have to declare the operator<< for your enum class type, but in the same namespace as the enum (see https://github.com/google/googletest/blob/main/docs/advanced.md#teaching-googletest-how-to-print-your-values)

namespace Foo
{
    enum class Bar
    {
        Hello,
        Goodbye,
    };

    // In the same namespace !!
    inline std::ostream& operator<<(std::ostream& os, const Bar& v)
    {
        switch (v)
        {
            case Bar::Hello: os << "Hello"; break;
            case Bar::Goodbye: os << "Goodbye"; break;
        }
        return os;
    }
}

TEST(Suite, Demo1)
{
    using namespace Foo;

    vector<Bar> vec1 = { Bar::Hello, Bar::Goodbye };
    vector<Bar> vec2 = { Bar::Goodbye };

    ASSERT_EQ(vec1, vec2);
}
test.cpp(106): error: Expected equality of these values:
  vec1
    Which is: { Hello, Goodbye }
  vec2
    Which is: { Goodbye }
[  FAILED  ] Suite.Demo1 (1 ms)

`` 

What I do is make a list-initialization ready print of the vectors and compare the two strings.

Something like this:

std::stringstream expected;
expected_triangles << expected_vector;

std::stringstream output;
o_triangles << output_vector;

EXPECT_EQ(o_triangles.str(), expected_triangles.str());

For this to work, you need to define:

///
/// \brief operator << print a vector in a list-initialization friendly format
/// \param out
/// \param point
/// \return
///
template <typename T>
std::ostream &operator<<(std::ostream &out, std::vector<T> const &vector) 

{
    out << "{";

    if (!vector.empty())
    {
        out << vector[0];
    }

    for (size_t i = 1; i < vector.size(); i++)
    {
        out << ", " << vector[i];
    }

    out << "}";

    return out;
}

It's very convenient also to create test cases from live data, since you just need to log the data and then use it to initialize your test array.

Related