Catch2 заставляет меня добавить приведение к std :: string в мои исключения, это может создать другие проблемы? - PullRequest
0 голосов
/ 02 июня 2019

Я использую Catch2 для написания своих модульных тестов.

Одна вещь, которую я хочу сделать, - убедиться, что я ловлю правильное исключение. Я выбрасываю одни и те же исключения во многих обстоятельствах, поэтому просто знание того, что я ловлю std::logic_error, не доказывает, что конкретный экземпляр исключения действительно был пойман.

Catch2 предоставляет макрос REQUIRE_THROWS_MATCHES() для этой цели.

Вот пример того, как я использую его с Equals matcher:

    CATCH_REQUIRE_THROWS_MATCHES(
                  std::make_shared<advgetopt::getopt>(
                            options_environment
                          , sub_argc
                          , sub_argv)
                , advgetopt::getopt_exception_logic
                , Catch::Matchers::Equals(
                          "section \"invalid::name\" includes a section separator (::) in \""
                        + options_filename
                        + "\". We only support one level."));

Только это не компилируется, если в моих исключениях нет оператора приведения. В этом случае это достаточно просто, так как у меня есть собственное исключение. Но мне интересно, почему автор Catch2 решил использовать приведение к std::string вместо использования функции what().

Вот мое текущее определение исключения базового класса :

class logic_exception_t
    : public std::logic_error
    , public exception_base_t
{
public:
    explicit                    logic_exception_t( std::string const & what, int const stack_trace_depth = STACK_TRACE_DEPTH );
    explicit                    logic_exception_t( char const *        what, int const stack_trace_depth = STACK_TRACE_DEPTH );

    virtual                     ~logic_exception_t() override {}

    virtual char const *        what() const throw() override;
                                operator std::string () const;
};

Вот функция operator std::string () const:

logic_exception_t::operator std::string () const
{
    return what();
}

Есть ли другой способ удовлетворить требование Catch2 и разрешить преобразование исключения в std::string без необходимости создания оператора приведения? Мне просто не нравится иметь актеров, которые могут вызвать другие проблемы в будущем.

Примечание: Я пытался сделать приведение явным, и Catch2 тоже не нравится. Он просто передает исключение в функцию, которая ожидает std::string.

1 Ответ

0 голосов
/ 02 июня 2019

На самом деле вы можете определить свой собственный наблюдатель, поэтому я решил написать наблюдатель, который бы исключил его функцию match().Это работает без приведения к std::string!

namespace Catch
{
namespace Matchers
{


class ExceptionWatcher
    : public MatcherBase<std::exception>
{
public:
    ExceptionWatcher(std::string const & expected_message)
        : m_expected_message(expected_message)
    {
    }

    /** \brief Check whether we got a match.
     *
     * This function compares the expected string with the actual exception
     * what() output.
     */
    bool match(std::exception const & e) const override
    {
        return e.what() == m_expected_message;
    }

    /** \brief Describe this matcher.
     *
     * This function produces a string describing what this matcher does.
     *
     * \return The description of this matcher.
     */
    virtual std::string describe() const override
    {
        return "compare the exception what() message with \""
             + m_expected_message
             + "\".";
    }

private:
    std::string     m_expected_message = std::string();
};


inline ExceptionWatcher ExceptionMessage(std::string const & expeted_message)
{
    return ExceptionWatcher(expeted_message);
}



}
// Matchers namespace
}
// Catch namespace
...