20

I have the following output from a Google Test unit test:

UnitTests.cc:56: Failure
Value of: LineSegment2i(Vector2i(-10,0), Vector2i(-10,10)).toLine()
  Actual: 24-byte object <00-00 00-00 00-00 24-C0 00-00 00-00 00-00 00-00 00-00 2F-2B FF-7F 00-00>
Expected: Line(10, 3.14159265358979323846)
Which is: 24-byte object <00-00 00-00 00-00 24-40 18-2D 44-54 FB-21 09-40 00-00 64-00 00-00 00-00>
[  FAILED  ] LineSegmentTests.toLine (1 ms)

That hexadecimal output string isn't very useful. Is there something I can add to the Line class (for which an equality test is failing) to provide more helpful errors in such cases?

The class in question has overridden the << operator as a member function:

std::ostream& operator<<(std::ostream& stream) const
{
  return stream << "Line (radius=" << d_radius << " theta=" << d_theta << ")";
}

You can see that this works for the 'Expected' line, but not the 'Actual' line. This statement is untrue — the test shown comes from the parameter of the TEST macro.

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742

3 Answers3

17

In order to print custom types you could "teach" Google Test how to print your custom types which as described in the section Teaching Google Test How to Print Your Values.

user686249
  • 669
  • 6
  • 17
lets_go_surfing
  • 345
  • 2
  • 5
12

The header in the gtest-printers.h source file provides an answer:

This file implements a universal value printer that can print a value of any type T:

void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr);

A user can teach this function how to print a class type T by defining either operator<<() or PrintTo() in the namespace that defines T. More specifically, the FIRST defined function in the following list will be used (assuming T is defined in namespace foo):

  1. foo::PrintTo(const T&, ostream*)
  2. operator<<(ostream&, const T&) defined in either foo or the global namespace.

If none of the above is defined, it will print the debug string of the value if it is a protocol buffer, or print the raw bytes in the value otherwise.

So it looks like the operator override needs to be a non-member function.

std::ostream& operator<<(std::ostream& stream, Line const& line)
{
  return stream << "Line (radius=" << line.radius() << " theta=" << line.theta() << ")";
}
Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
  • Is there something more needed if my type is a class template? I have `operator<<` defined in the namespace. If I have `EXPECT_EQ(v1, v2) << v1 << ' ' << v2;`, the expected and actual values print in the "xx-byte object" format but my addendum successfully invokes my custom printer. – Adrian McCarthy Jul 01 '21 at 16:16
3

In some cases it may better to provide a PrintTo() function instead of a stream operator. E.g. if you want to customize how a container (having begin()/end()) is printed, the existing internal operators of Google Test will currently have priority over custom operators. In that case your operator will not work but a PrintTo() function will. Definition looks like this:

void PrintTo(const Range& range, ::std::ostream* os)
{
   *os << range;
}

Also see here: https://github.com/google/googletest/issues/3458

Silicomancer
  • 8,604
  • 10
  • 63
  • 130