0

I'm new to unit testing in C++ with Catch2. Lastly, I was trying to implement a custom Matcher to test if the fields of a given object match the ones I provide. The object in question would be like:

class Book {
private:
    int chapters;
    int pages;

public:
    int GetChapters();
    int GetPages();
};

My matcher would be used like this in a test case:

TEST_CASE("Books info is correct")
{
    Book myBook;
    CHECK_THAT(myBook, IsCorrect(5, 150));
    CHECK_THAT(myBook, IsCorrect(10, 325));
}

Following the example in the documentation, my intent has been:

// The matcher class
class BookCheck : public Catch::MatcherBase<Book> {
    Book book;
    int chapters = -1;
    int pages = -1;

public:
    BookCheck(int chapters, int pages) : chapters(chapters), pages(pages) {}

    // Performs the test for this matcher
    bool match( Book& b ) const override {
        return b.GetChapters() == chapters && b.GetPages() == pages;
    }

    virtual std::string describe() const override {
        ostringstream ss;
        //ss << "is between " << m_begin << " and " << m_end; // TODO
        return ss.str();
    }
};

// The builder function
inline BookCheck IsCorrect(int chapters, int pages) {
    return BookCheck(chapters, pages);
}

When I compile this code, I get this errors:

error: ‘bool BookCheck::match(Book&) const’ marked ‘override’, but does not override

error: invalid abstract return type ‘BookCheck’

error: invalid abstract return type for function ‘BookCheck IsCorrect(int, int)’

error: invalid cast to abstract class type ‘BookCheck’

Could you point me what am I doing wrong here?

chick3n0x07CC
  • 678
  • 2
  • 10
  • 30
  • The example you linked to uses a `const` parameter for `match()`. Does changing `Book&` to `const Book&` do anything? http://www.coolprop.org/dev/_static/doxygen/html/struct_catch_1_1_matchers_1_1_impl_1_1_matcher_method.html – parktomatomi Feb 06 '20 at 18:13

1 Answers1

2

Your match method override is ill-formed.Catch::MatcherBase::match takes object as reference-to-const, so object will not be modified in method body. Signature for Catch::MatcherBase::match is:

virtual bool match(ObjectT const& arg) const

So Your match override implementation should be:

bool match(Book const& b) const override {
    return b.GetChapters() == chapters && b.GetPages() == pages;
}

Additionally You need to mark Your Book getters const in order to keep const correctness:

int GetChapters() const;
int GetPages() const;
wehubert
  • 86
  • 5