GoogleTest PrintTo不被要求上课 [英] GoogleTest PrintTo not getting called for a class

查看:107
本文介绍了GoogleTest PrintTo不被要求上课的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个很奇怪的问题,告诉googletest以我想要使用PrintTo的方式打印特定的类.
该类是一个非常简单的2D点,它在名称空间中,而PrintTo函数在相同的名称空间中.实际上,我有一个派生类(3D点),可以完美打印.

I'm having a rather strange problem telling googletest to print a certain class the way I want using PrintTo.
The class is a very simple 2D point, it is in a namespace and the PrintTo function is in the same namespace. In fact, I have a derived class (a 3D point) which prints perfectly.

以下是用于测试和PrintTo函数的代码(已编辑名称空间名称,但其他所有内容均已从实际代码中复制并粘贴):

Here's some code for the tests and PrintTo functions (namespace name 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)

我试图在一个简单的测试项目中复制该问题,但是在这里打印效果很好.我可以想到的是,在测试项目和真实项目之间的唯一区别是,在真实项目中,CPunto2D和CPunto3D类都在dll中,当然有更多的类,并且它们依赖于库.

I've tried to replicate the issue in a simple test project, but there it prints perfectly. The only difference I can think of between the test project and the real one is that in the real one the classes CPunto2D and CPunto3D are in a dll, with more classes, of course, and they depend on a library.

关于为什么不选择PrintTo函数的任何想法吗?

Any idea on why it's not picking the PrintTo function?

我正在使用Visual Studio 2008和googletest 1.7

I'm using Visual Studio 2008 and googletest 1.7

注意:即使该示例使用GMock的ASSERT_THAT,我也已使用ASSERT_EQ对其进行了尝试,并且相同.

Note: Even though the example uses GMock's ASSERT_THAT, I've tried it with ASSERT_EQ and it's the same.

更新:

这是CPunto2D和CPunto3D的声明. CLAS_DEC只是用于从dll导入/导出的宏.我知道上课有上百万种错误,例如公共成员之类的,所以,如果与当前问题不相关,请不要指出这些错误.

Here are the declarations of CPunto2D and CPunto3D. CLAS_DEC is just a macro for importing/exporting from the dll. I know there are like a million things wrong with the classes, like public members and such, so please don't point those thing out if it's not relevant to the problem at hand.

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

推荐答案

问题是您破坏了 O ne D 定义 R ( ODR )之一的gtest函数 (可能是template ::testing::PrintToString<MyNamespace::CPunto2D>(const MyNamespace::CPunto2D&)).

Problem is that you break the One Definition Rule (ODR) of one of the gtest function (probably template ::testing::PrintToString<MyNamespace::CPunto2D>(const MyNamespace::CPunto2D&)).

在使用ASSERT_EQ的一个TU中,未声明void PrintTo(const MyNamespace::CPunto2D& pto, ::std::ostream* os), 因此::testing::PrintToString<MyNamespace::CPunto2D>使用默认打印机.

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

在另一个使用ASSERT_EQ的TU中,您声明了(可能定义了)void PrintTo(const MyNamespace::CPunto2D& pto, ::std::ostream* os),因此::testing::PrintToString<MyNamespace::CPunto2D>使用的是使用自定义PrintTo的版本.

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

这是同一功能的秒不同定义.

您必须确保每个使用ASSERT_EQ的TU都可以看到自定义PrintTo的声明(如CPunto2D的标题中一样).

You have to make sure that each TU which uses ASSERT_EQ see the declaration of your custom PrintTo (as in CPunto2D's header).

这篇关于GoogleTest PrintTo不被要求上课的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆