2014-07-10 4 views
6

Ich habe ein ziemlich seltsames Problem googletest, eine bestimmte Klasse zu drucken, wie ich PrintTo verwenden möchte.
Die Klasse ist ein sehr einfacher 2D-Punkt, sie befindet sich in einem Namespace und die PrintTo-Funktion befindet sich im selben Namespace. Tatsächlich habe ich eine abgeleitete Klasse (einen 3D-Punkt), die perfekt druckt.GoogleTest PrintTo nicht für eine Klasse aufgerufen werden

Hier ist ein Code für die Tests und PrintTo Funktionen (Namespace-Namen bearbeitet, aber alles andere kopiert und von dem eigentlichen Code eingefügt):

// 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) 

Ich habe versucht, das Problem in einem einfachen Test zu replizieren Projekt, aber dort druckt es perfekt. Der einzige Unterschied, den ich zwischen dem Testprojekt und dem echten Projekt feststellen kann, ist, dass die Klassen CPunto2D und CPunto3D in der DLL liegen, natürlich mit mehr Klassen, und sie hängen von einer Bibliothek ab.

Irgendeine Idee, warum es die PrintTo-Funktion nicht auswählt?

ich Visual Studio 2008 und googletest 1.7

Hinweis bin mit: Auch wenn das Beispiel GMock die ASSERT_THAT verwendet, habe ich es mit ASSERT_EQ versucht, und es ist das gleiche.

UPDATE:

Hier sind die Erklärungen von CPunto2D und CPunto3D. CLAS_DEC ist nur ein Makro zum Importieren/Exportieren von der DLL. Ich weiß, dass mit den Klassen wie mit öffentlichen Mitgliedern und so etwas wie eine Million Dinge nicht stimmen, also bitte zeigen Sie diese Dinge nicht auf, wenn es für das vorliegende Problem nicht relevant ist.

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 
    }; 
} 
+0

Entschuldigung: Die Klassen sind in einer DLL definiert und Sie verwenden diese von dort, aber definieren die Druckmethoden in Ihrer App? –

+0

Ja. Nun, nicht in der endgültigen App. Im Test cpp. Sollte es nicht funktionieren? – MikMik

+0

Es könnte ein Name Auflösung Problem sein, ich bin mir nicht sicher, um ehrlich zu sein –

Antwort

6

Problem ist, dass Sie die O ne D efinition R ule (ODR) eines der Gtest Funktion (wahrscheinlich template ::testing::PrintToString<MyNamespace::CPunto2D>(const MyNamespace::CPunto2D&)) brechen.

In einer TU, wo Sie ASSERT_EQ verwenden, wird void PrintTo(const MyNamespace::CPunto2D& pto, ::std::ostream* os) nicht erklärt, so verwendet ::testing::PrintToString<MyNamespace::CPunto2D> den Standarddrucker.

In einer anderen TU wo Sie ASSERT_EQ verwenden, haben Sie void PrintTo(const MyNamespace::CPunto2D& pto, ::std::ostream* os) erklärt (und möglicherweise definiert ist), so verwendet ::testing::PrintToString<MyNamespace::CPunto2D> eine Version Ihrer benutzerdefinierten mit PrintTo.

Das ist eine zweite unterschiedliche Definition der gleichen Funktion.

Sie müssen sicherstellen, dass jede TU, die ASSERT_EQ verwendet, sehen Sie die Deklaration Ihrer benutzerdefinierten PrintTo (wie in CPunto2D Header).

Verwandte Themen