用于检查是不是抛出异常的 C++ 断言函数

Posted

技术标签:

【中文标题】用于检查是不是抛出异常的 C++ 断言函数【英文标题】:C++ Assertion function to check that Exception is thrown用于检查是否抛出异常的 C++ 断言函数 【发布时间】:2013-03-27 20:01:38 【问题描述】:

我熟悉标准 C++ 断言的工作原理。这在我的项目中运行良好,可用于各种测试目的。

例如,假设我想检查我的代码是否引发了某个异常。

如果不使用像 CPPUnit 这样的测试框架,这可能吗?

【问题讨论】:

基于帖子:***.com/questions/37473/…。编写一个使用catch 的宏怎么样? 【参考方案1】:

你可以手动做同样的事情CPPUnit does:

bool exceptionThrown = false;

try

    // your code

catch(ExceptionType&) // special exception type

    exceptionThrown = true;

catch(...) // or any exception at all

    exceptionThrown = true;


assert(exceptionThrown); // or whatever else you want to do

当然,如果你经常使用这种模式,那么为此使用宏是有意义的。

【讨论】:

【参考方案2】:

骨架(未测试)

#define MY_ASSERT(f, e) \
    try \
        f();\
     catch (std::exception &e) \
        ...\
    \

【讨论】:

【参考方案3】:

这是我根据@JPlatte 和@gongzhitaao 的回答编写的异常测试器。对于我的测试框架,我有两个全局变量 num_testnum_test_success 来跟踪执行了多少测试以及在一系列测试中成功的测试数量,但可以根据您的需要进行更改。

int num_test;
int num_test_success;

#define UT_ASSERT_THROW(expression, ExceptionType)             \
                                                                \
    try                                                        \
        expression;                                             \
        printf("test %d:    *** FAILURE ***     %s:%d:%s,%s\n", \
               num_test, __FILE__, __LINE__,                    \
               #expression, #ExceptionType);                    \                                 
     catch (const ExceptionType &)                            \
        printf("test %d:    success\n", num_test);              \
        ++num_test_success;                                     \
     catch (...)                                              \
        printf("test %d:    *** FAILURE ***     %s:%d:%s,%s\n", \
               num_test, __FILE__, __LINE__,                    \ 
               #expression, #ExceptionType);                    \
                                                               \
                                                                \
    ++num_test;                                                 \
                                                                \

__FILE____LINE__ 扩展为当前文件和行号(参见https://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html)。宏内部的井号告诉预处理器将参数作为字符串放入宏扩展中(参见http://bruceblinn.com/linuxinfo/Stringification.html)。

【讨论】:

【参考方案4】:

代码内断言通常用于方法的开头,以便在进入此特定功能之前确认满足某些先决条件 例如:

Window::paint()

  assert(m_device != NULL);
  m_device->repaintRegion();

他们在这里主要是为了捕捉错误,方法或类之间未满足的依赖关系。

测试框架中的断言不同,通常用于单元测试,以确保单元返回它需要返回的任何内容。

通常应该在现实(即外部系统)为我们提供代码不能/不应该处理的情况下抛出异常。这是解决罕见但仍可预期的问题的简单方法。例如 - 等待服务器通常可用的超时。或者,内存不足。我不会将它用作编程逻辑的辅助工具。

对于您的问题,可能有一种方法可以通过使用 try-catch 包围测试的单元来捕获测试框架中的异常。但我不确定它是否真的可取。

HTH

【讨论】:

我看不出这有什么帮助。

以上是关于用于检查是不是抛出异常的 C++ 断言函数的主要内容,如果未能解决你的问题,请参考以下文章

PHPUnit 断言抛出异常?

python 断言

检查单元测试中是不是抛出参数

C++的构造函数可以抛出异常么

如何处理未经检查的异常?

Java核心技术 卷Ⅰ 基础知识