Customise actual/expected "Value of" string in Google Test failure output messages
Asked Answered
G

3

21

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.

Gradus answered 3/3, 2013 at 21:17 Comment(0)
F
19

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.

Floccule answered 3/3, 2013 at 21:28 Comment(0)
G
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() << ")";
}
Gradus answered 3/3, 2013 at 21:28 Comment(1)
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.Bibb
C
4

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

Coyote answered 14/8, 2021 at 20:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.