1

我正在使用Catch2编写单元测试。

我想做的一件事是确保我捕捉到了正确的异常。在许多情况下我都会抛出相同的异常,因此仅知道我正在捕获 anstd::logic_error并不能证明确实捕获了异常的特定实例。

Catch2 为此提供了REQUIRE_THROWS_MATCHES()宏。

这是我如何将它与Equals匹配器一起使用的示例:

    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 要求并允许将异常转换为 anstd::string而无需创建强制转换运算符?我只是不喜欢演员阵容,这可能会导致其他问题。

注意:我试图使演员表明确,而 Catch2 也不喜欢它。它只是将异常传递给需要std::string.

4

1 回答 1

0

你实际上可以定义你自己的观察者,所以我决定写一个观察者,它的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
于 2019-06-02T03:28:04.187 回答