答案:c++异常测试通过google Test的EXPECT_THROW等宏验证异常是否按预期抛出,结合自定义异常类和异常消息检查,覆盖越界访问、除零、无效参数等场景,确保关键路径的容错能力。
在C++中,异常测试是确保程序在遇到错误条件时能够正确抛出异常并保持稳定的重要手段。尤其在编写健壮的库代码或关键业务逻辑时,验证异常是否按预期抛出非常必要。以下是常用的C++异常测试方法及具体的异常触发测试案例。
使用断言检查异常抛出
在测试中,我们通常使用断言来验证某段代码是否会抛出特定异常。现代C++测试框架(如Google Test)提供了专门的宏来捕获异常。
以Google Test为例,EXPECT_THROW、EXPECT_ANY_THROW 和 EXPECT_NO_THROW 是常用的异常测试宏:
- EXPECT_THROW(stmt, exception_type):验证语句是否抛出指定类型的异常
- EXPECT_ANY_THROW(stmt):验证语句是否抛出任意异常
- EXPECT_NO_THROW(stmt):验证语句不抛出任何异常
示例代码:
立即学习“C++免费学习笔记(深入)”;
#include <gtest/gtest.h> #include <stdexcept> #include <vector> <p>// 被测函数:访问越界时抛出异常 int AccessElement(const std::vector<int>& vec, size_t index) { if (index >= vec.size()) { throw std::out_of_range("Index out of range"); } return vec[index]; }</p><p>// 测试案例:验证越界访问抛出 out_of_range TEST(ExceptionTest, OutOfRangeThrows) { std::vector<int> data = {1, 2, 3}; EXPECT_THROW(accessElement(data, 5), std::out_of_range); EXPECT_NO_THROW(accessElement(data, 1)); }</p>
自定义异常类的测试
当使用自定义异常类型时,测试需要确保正确的异常类型被抛出。
示例:自定义异常并测试
struct InvalidInputException : public std::exception { const char* what() const noexcept override { return "Invalid input provided"; } }; <p>// 被测函数:输入为负数时抛出异常 void processPositiveOnly(int value) { if (value < 0) { throw InvalidInputException(); } }</p><p>TEST(ExceptionTest, CustomExceptionThrown) { EXPECT_THROW(processPositiveOnly(-1), InvalidInputException); EXPECT_NO_THROW(processPositiveOnly(10)); }</p>
测试异常消息内容(高级)
有时需要验证异常的错误消息是否符合预期。这需要捕获异常对象本身。
TEST(ExceptionTest, ExceptionMessageIsCorrect) { std::vector<int> empty; try { accessElement(empty, 0); FaiL() << "Expected std::out_of_range"; } catch (const std::out_of_range& e) { EXPECT_STREQ(e.what(), "Index out of range"); } }
这种写法在Google Test中更灵活,适用于需要深度验证异常内容的场景。
常见异常触发测试案例
以下是一些典型的异常触发测试场景:
- 容器越界访问(如 vector、Array)
- 空指针解引用前检查(抛出自定义异常)
- 除零操作(可封装为函数抛出)
- 无效参数校验(如负数作为数组大小)
- 资源分配失败(如 new 失败且未使用nothrow)
示例:除零异常测试
double divide(double a, double b) { if (b == 0.0) { throw std::invalid_argument("Division by zero"); } return a / b; } <p>TEST(ExceptionTest, DivisionByZeroThrows) { EXPECT_THROW(divide(10, 0), std::invalid_argument); }</p>
基本上就这些。只要结合测试框架和合理的异常设计,C++中的异常测试就能有效保障代码的容错能力。关键是覆盖关键路径,确保异常在正确时机以正确类型抛出。不复杂但容易忽略。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END