测试特定的异常类型被抛出并且异常具有正确的属性

新手上路,请多包涵

我想测试 MyException 在某种情况下被抛出。 EXPECT_THROW 在这里很好。但我也想检查异常是否具有特定状态,例如 e.msg() == "Cucumber overflow"

这在 GTest 中如何最好地实现?

原文由 Mr. Boy 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 515
2 个回答

我主要是第二个 Lilshieste 的回答,但要补充一点,您还应该验证没有抛出 错误 的异常类型:

 #include <stdexcept>
#include "gtest/gtest.h"

struct foo
{
    int bar(int i) {
        if (i > 100) {
            throw std::out_of_range("Out of range");
        }
        return i;
    }
};

TEST(foo_test,out_of_range)
{
    foo f;
    try {
        f.bar(111);
        FAIL() << "Expected std::out_of_range";
    }
    catch(std::out_of_range const & err) {
        EXPECT_EQ(err.what(),std::string("Out of range"));
    }
    catch(...) {
        FAIL() << "Expected std::out_of_range";
    }
}

int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

原文由 Mike Kinghan 发布,翻译遵循 CC BY-SA 3.0 许可协议

我找到了 Brandlingo( 宏解决方案)给出的原始答案,以创造比 EXPECT_THAT 替代方案更好的体验,如果您需要以非平凡的方式检查异常的内容,这仍然是有限的。

Brandlingo 的回答有一些警告,尽管我已经在这里解决了:

  1. 通过嵌套 try 块并仅在发生预期异常时才将其抛出到外部块,删除了使多次使用变得烦人的 unscoped exception_ptr。
  2. 假设任何意外异常源自 std::exception,并打印“what()”的值。对于提供有关发生的事情的提示很有用。如果异常不是从 std::exception 派生的,测试仍然会失败,你只是不会得到行号。您可以通过添加另一个捕获来处理它,但这确实不应该发生。
  3. 传入要用于异常的变量的名称(为了便于阅读)。
 #define ASSERT_THROW_AND_USE(statement, expected_exception, exception_varname)                   \
    try {                                                                                         \
        try {                                                                                     \
            (statement);                                                                          \
            FAIL() << "Expected: " #statement " throws an exception of type " #expected_exception \
                      ".\n  Actual: it throws nothing.";                                          \
        } catch (const expected_exception&) {                                                     \
            throw;                                                                                \
        } catch (const std::exception& e) {                                                       \
            FAIL() << "Expected: " #statement " throws an exception of type " #expected_exception \
                      ".\n  Actual: it throws a different type, with message: "                   \
                   << std::quoted(e.what());                                                      \
        }                                                                                         \
    } catch (const expected_exception& exception_varname)

然后像这样使用它:

 ASSERT_THROW_AND_USE(foo(), MyException, e)
{
    ASSERT_STREQ("fail message", e.MyMethod());
}

如果抛出了错误的异常,你会得到如下信息:

 Failed
Expected: foo() throws an exception of type MyException.
  Actual: it throws a different type, with message: "some other thing"

原文由 Bryant 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题