GoogleTest PrintTo does not receive call for class

I have a rather strange problem telling googletest about printing a specific class as I want using PrintTo.
A class is a very simple two-dimensional point, it is in the namespace, and the PrintTo function is in the same namespace. In fact, I have a derived class (3D dot) that prints fine.

Here is the code for the tests and the PrintTo function (the namespace name has been edited, but everything else is copied and pasted from the actual code):

// PrintTo Functions namespace MyNamespace { void PrintTo(const MyNamespace::CPunto2D& pto, ::std::ostream* os) { *os << "("; *os << pto.X(); *os << ","; *os << pto.Y(); *os << ")"; } void PrintTo(const MyNamespace::CPunto3D& pto, ::std::ostream* os) { *os << "("; *os << pto.X(); *os << ","; *os << pto.Y(); *os << ","; *os << pto.m_Z; *os << ")"; } } // Tests TEST(TestPrintTo, TestPunto2D) { MyNamespace::CPunto2D p1(1,1); MyNamespace::CPunto2D pRef(5,6); ASSERT_THAT(p1, Eq(pRef)); } TEST(TestPrintTo, TestPunto3D) { MyNamespace::CPunto3D pCentro(1,1,1); MyNamespace::CPunto3D pRef(5,6,7); ASSERT_THAT(pCentro, Eq(pRef)); } // Output [ RUN ] TestPrintTo.TestPunto2D .\TestPuntoEje.cpp(82): error: Value of: p1 Expected: is equal to 16-byte object <00-00 00-00 00-00 14-40 00-00 00-00 00-00 18-40> Actual: 16-byte object <00-00 00-00 00-00 F0-3F 00-00 00-00 00-00 F0-3F> (of type class MyNamespace::CPunto2D) [ FAILED ] TestPrintTo.TestPunto2D (1 ms) [ RUN ] TestPrintTo.TestPunto3D .\TestPuntoEje.cpp(90): error: Value of: pCentro Expected: is equal to (5,6,7) Actual: (1,1,1) (of type class MyNamespace::CPunto3D) [ FAILED ] TestPrintTo.TestPunto3D (0 ms) 

I tried to reproduce the problem in a simple test project, but there it prints fine. The only difference that I can imagine between a test project and a real one is that in the real class, the CPunto2D and CPunto3D classes are in the dll, with a lot of classes, and they depend on the library.

Any idea on why he doesn't select the PrintTo function?

I am using Visual Studio 2008 and googletest 1.7

Note. Although the example uses GMock ASSERT_THAT, I tried it with ASSERT_EQ and it is the same.

UPDATE:

Here are the CPunto2D and CPunto3D announcements. CLAS_DEC is just a macro to import / export from dll. I know that in classes there is something like a million things, such as public participants, etc. Therefore, please do not point this out if this does not apply to the problem.

 namespace MyNamespace { class CLAS_DEC CPunto2D { public: double m_X; double X() const { return m_X; } void X(double val) { m_X = val; } double m_Y; double Y() const { return m_Y; } void Y(double val) { m_Y = val; } //Constructores/Destructores CPunto2D(); CPunto2D(double X, double Y); CPunto2D(const CPunto2D& P); ~CPunto2D(); CPunto2D& Set(double X, double Y); //Operadores CPunto2D& operator =(const CPunto2D& P); //Funciones extra double Distancia (const CPunto2D& P) const; //Distancia a otro punto }; bool CLAS_DEC operator==(const CPunto2D& lhs, const CPunto2D& rhs); bool CLAS_DEC operator!=(const CPunto2D& lhs, const CPunto2D& rhs); } namespace MyNamespace { class CLAS_DEC CPunto3D : public CPunto2D { public: double m_Z; // Constructores/Destructores CPunto3D(); CPunto3D(double X, double Y, double Z); CPunto3D(const CPunto3D& P); CPunto3D(const CPunto2D& P); ~CPunto3D(); CPunto3D& Set(double X, double Y, double Z); // Operadores CPunto3D& operator =(const CPunto3D& P); bool operator==(const CPunto3D& P) const; bool operator!=(const CPunto3D& P) const; // Funciones Extra double Distancia (const CPunto3D& P) const; //Distancia a otro punto double Distancia2D (const CPunto2D& P) const; //Distancia en el plano a otro punto }; } 
+7
c ++ one-definition-rule googletest
source share
1 answer

The problem is that you are violating O ne D efinition R ule ( ODR ) of one of the most reliable functions (perhaps template ::testing::PrintToString<MyNamespace::CPunto2D>(const MyNamespace::CPunto2D&) ).

In one TU where you use ASSERT_EQ , void PrintTo(const MyNamespace::CPunto2D& pto, ::std::ostream* os) not declared, so ::testing::PrintToString<MyNamespace::CPunto2D> uses the default printer.

In another TU where you use ASSERT_EQ , you have void PrintTo(const MyNamespace::CPunto2D& pto, ::std::ostream* os) declared (and potentially specific), so ::testing::PrintToString<MyNamespace::CPunto2D> uses version using your custom PrintTo .

This is the second other definition of the same function.

You must make sure that every TU that uses ASSERT_EQ sees your custom PrintTo (as in the CPunto2D header).

+6
source share

All Articles