1
TEST_CASE("Functions of Square")
{
    std::array<Point, 4> a_Vertices{Point(2, 2), Point(2, 4), Point(4, 2), Point(4, 4)};
    Square a_Square(a_Vertices, true);

    SECTION("Square is initialized properly")
    {
        REQUIRE(a_Square.get_Vertex_0() == Point(2, 1));
    }
}

使用 catch2 单元测试框架,我想覆盖 catch2 describe 方法,以便它打印出我的类型而不是 {?} == {?}

我也试过通过 matcher 方法来做

class Point_Matcher : public Catch::MatcherBase<Point>
{
private:
    Point p_;

public:
    Point_Matcher(const Point &a_Point)
        : p_(a_Point) {}

    bool match(Point const &a_Point) const override
    {
        return a_Point == p_;
    }

    virtual std::string describe() const override
    {
        std::ostringstream oss;
        oss << "not the same as Point (" << p_.get_X() << ", " << p_.get_Y() << ")";
        return oss.str();
    }
};

inline Point_Matcher is_Same(const Point &a_Point)
{
    return Point_Matcher(a_Point);
}

TEST_CASE("Functions of Square")
{
    std::array<Point, 4> a_Vertices{Point(2, 2), Point(2, 4), Point(4, 2), Point(4, 4)};
    Square a_Square(a_Vertices, true);

    SECTION("Square is initialized properly")
    {
        REQUIRE_THAT(a_Square.get_Vertex_0(), is_Same(Point(2, 1)));
    }
}

但是,它只会显示指定为测试的对象,而不会显示正在测试的对象。输出将是 {?} 与 Point(2, 1) 不同

https://github.com/catchorg/Catch2/blob/master/docs/tostring.md#top 建议的方法是覆盖 std::ostream 的运算符<<,但是,我不知道重载运算符后我应该做什么。

预先感谢您的回答

编辑: 点对象的 operator<< 的重载如下

std::ostream &operator<<(std::ostream &os, const Point &p)
{
    os << "Point (" << p.get_X() << ", " << p.get_Y();
    return os;
}

换句话说,在这种情况下,我的目标输出特别是 Point(x, y) 与 Point(x,y) 不同

4

1 回答 1

1

有两种常用的方法。两者都在您提到的文档中进行了描述。

  1. 运算符 << std::ostream 的重载,具有以下限制:

您应该将此函数放在与您的类型或全局名称空间相同的名称空间中,并在包含 Catch 的标头之前声明它。

所以,你的操作符重载是可以的,只要把它放在#include "catch.hpp".

#define CATCH_CONFIG_MAIN
#include <array>
#include "Point.h"
#include "Square.h"    

std::ostream &operator<<(std::ostream &os, Point const& p)
{
    os << "Point (" << p.get_X() << ", " << p.get_Y() << ")";
    return os;
}

#include "catch.hpp"

TEST_CASE("Functions of Square")
{
    std::array<Point, 4> a_Vertices{Point(2, 2), Point(2, 4), Point(4, 2), Point(4, 4)};
    Square a_Square(a_Vertices, true);

    SECTION("Square is initialized properly")
    {
        REQUIRE_THAT(a_Square.get_Vertex_0(), is_Same(Point(2, 1)));
    }
}

2. Catch::StringMaker 专业化,使用额外的字符串流来正确格式化您的输出。

#define CATCH_CONFIG_MAIN
#include <array>
#include <sstream>
#include "Point.h"
#include "Square.h"
#include "catch.hpp"

namespace Catch
{
template <> struct StringMaker<Point>
{
    static std::string convert(Point const& p)
    {
        std::stringstream buf;
        buf << "Point (" << p.get_X() << ", " << p.get_Y() << ")";
        return << buf.str();
    }
};
}

TEST_CASE("Functions of Square")
{
    std::array<Point, 4> a_Vertices{Point(2, 2), Point(2, 4), Point(4, 2), Point(4, 4)};
    Square a_Square(a_Vertices, true);

    SECTION("Square is initialized properly")
    {
        REQUIRE_THAT(a_Square.get_Vertex_0(), is_Same(Point(2, 1)));
    }
}    

这种方法避免了全局命名空间污染,并允许您屏蔽任何其他先前定义<<的运算符。StringMaker首先将使用专业化。

于 2020-02-24T18:48:27.460 回答