2014-07-10 6 views
6

Ho un problema piuttosto strano che dice a googletest di stampare una determinata classe nel modo in cui voglio usare PrintTo.
La classe è un punto 2D molto semplice, si trova in uno spazio dei nomi e la funzione PrintTo si trova nello stesso spazio dei nomi. In effetti, ho una classe derivata (un punto 3D) che stampa perfettamente.GoogleTest PrintPer non ricevere chiamate per una classe

Ecco po 'di codice per le prove e le funzioni printto (nome dello spazio dei nomi editato, ma tutto il resto viene copiato e incollato dal codice vero e proprio):

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

Ho cercato di replicare il problema in un semplice test progetto, ma lì stampa perfettamente. L'unica differenza che posso pensare tra il progetto di test e quello reale è che in quello reale le classi CPunto2D e CPunto3D sono in una DLL, con più classi, ovviamente, e dipendono da una libreria.

Qualche idea sul motivo per cui non sta selezionando la funzione PrintTo?

sto usando Visual Studio 2008 e googletest 1,7

Nota: Anche se l'esempio utilizza ASSERT_THAT di GMock, ho provato con ASSERT_EQ ed è lo stesso.

UPDATE:

Ecco le dichiarazioni di CPunto2D e CPunto3D. CLAS_DEC è solo una macro per l'importazione/esportazione dalla dll. So che ci sono un milione di cose che non vanno nelle classi, come membri pubblici e così via, quindi per favore non puntare a quelle cose se non sono rilevanti per il problema in questione.

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

Ci scusiamo: le classi sono definite in una dll e stai utilizzando quelle da lì ma definisci i metodi di stampa nella tua app? –

+0

Sì. Bene, non nell'app finale. Nel test cpp. Non dovrebbe funzionare? – MikMik

+0

Potrebbe essere un problema di risoluzione dei nomi, non sono sicuro che sia onesto –

risposta

6

Il problema è che si spezza la O ne D efinizione R ULE (ODR) di una delle funzioni GTEST (probabilmente template ::testing::PrintToString<MyNamespace::CPunto2D>(const MyNamespace::CPunto2D&)).

In una TU in cui si usa ASSERT_EQ, void PrintTo(const MyNamespace::CPunto2D& pto, ::std::ostream* os) non è dichiarato, in modo ::testing::PrintToString<MyNamespace::CPunto2D> utilizza la stampante predefinita.

In un'altra TU in cui si utilizza ASSERT_EQ, avete void PrintTo(const MyNamespace::CPunto2D& pto, ::std::ostream* os) dichiarato (e potenzialmente definito), in modo da ::testing::PrintToString<MyNamespace::CPunto2D> utilizza una versione con la vostra abitudine PrintTo.

Questa è una seconda diversa definizione della stessa funzione.

È necessario assicurarsi che ogni TU che utilizza ASSERT_EQ veda la dichiarazione della propria PrintTo personalizzata (come nell'intestazione CPunto2D).

Problemi correlati