c++ GoogleTest PrintTo不被调用类

mwyxok5s  于 11个月前  发布在  Go
关注(0)|答案(3)|浏览(89)

我有一个相当奇怪的问题,告诉googletest打印某个类的方式,我想使用PrintTo。
这个类是一个非常简单的2D点,它在一个命名空间中,PrintTo函数也在同一个命名空间中。事实上,我有一个派生类(一个3D点),它可以完美地打印。
下面是测试和PrintTo函数的一些代码(命名空间名称已编辑,但其他所有内容都是从实际代码中复制和粘贴的):

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

字符串
我试着在一个简单的测试项目中复制这个问题,但它打印得很完美。我能想到的测试项目和真实的项目之间的唯一区别是,在真实的项目中,类CPunto 2D和CPunto 3D在一个dll中,当然有更多的类,它们依赖于一个库。
知道为什么它不选择PrintTo函数吗?
我正在使用Visual Studio 2008和GoogleTest 1.7
注意:尽管这个例子使用了GMock的ASSERT_THAT,但我已经用ASSERT_EQ试过了,结果是一样的。

更新:

这里是CPunto 2D和CPunto 3D的声明。CLAS_DEC只是一个从dll导入/导出的宏。我知道类有一百万个错误,比如公共成员等等,所以如果它与手头的问题无关,请不要指出这些东西。

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

ccrfmcuu

ccrfmcuu1#

问题是你破坏了一个gtest函数(可能是template ::testing::PrintToString<MyNamespace::CPunto2D>(const MyNamespace::CPunto2D&))的OneD定义Rule(ODR)。
在使用ASSERT_EQ的TU中,未声明void PrintTo(const MyNamespace::CPunto2D& pto, ::std::ostream* os),因此::testing::PrintToString<MyNamespace::CPunto2D>使用默认打印机。
在另一个使用ASSERT_EQ的TU中,您声明了void PrintTo(const MyNamespace::CPunto2D& pto, ::std::ostream* os)(并可能定义了void PrintTo(const MyNamespace::CPunto2D& pto, ::std::ostream* os)),因此::testing::PrintToString<MyNamespace::CPunto2D>使用的版本使用您的自定义PrintTo
这是同一个函数的第二个不同的定义。
您必须确保每个使用ASSERT_EQ的TU都看到了自定义PrintTo的声明(如CPunto2D的头文件)。

hwamh0ep

hwamh0ep2#

我的例子是MyType有一个ostream& operator<<(),但它是在mytype_io.h而不是mytype.h中定义的。如果任何单元测试cpp文件使用MyType但不包括mytype_io.h,那么它将导致gtest-printers.h中的默认模板实现被示例化。
所以我的类型没有被正确地打印出来。修复方法是确保所有使用MyType的单元测试都包含mytype_io.h

fae0ux8s

fae0ux8s3#

另一种可能发生这种情况的情况是,如果您定义了一个mock对象,其中有问题的类型被用作其中一个mock函数的参数。如果您在mock定义之后定义了打印机,那么gmock会以某种方式“锁定”备用打印机,而不是您定义的打印机。

相关问题