Implement ASSERT_THROWS(expr,ET) with exception matcher instead of typename

XMLWordPrintableJSON

    • Type: Improvement
    • Resolution: Unresolved
    • Priority: Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • Server Programmability
    • Programmability 2026-01-19, Programmability 2026-02-02
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      We are doing this just as an interim step to get these tests to compile:

      #define ASSERT_THROWS(EXPRESSION, TYPE) \
          ASSERT_THROW((void)(EXPRESSION), TYPE)
      

      From the project work doc:

      Add a flavor of ASSERT_THROW (link) that takes a matcher on the caught exception. {{ASSERT_THAT([&]
      Unknown macro: { (void)(expr); }
      , Throws<E>(...))}} (link) is close, however it has some problems. Users need to pass a lambda rather than just an expression, and the diagnostics suffer because it tries to stringify the lambda (yuck!). Might be able to work around this by wrapping the lambda in a type with a better stringification, but that wrapping (and the lambda) will show up as noise in the failure message. Probably better to just write the try/catch macro.

      We already have ASSERT_THROWS_WITH_CHECK() which is close (link). We should continue using it for assertion checking or replace it with a matcher version rather than using gtest's equivalents for now. But we should enhance its format to be closer to gtest's, e.g. by using newlines and Actual: prefixes.

      For reference, that format is included here in gtest's implementation:

      #define GTEST_TEST_THROW_(statement, expected_exception, fail)              \
        ... \
        catch (...) {                                                           \
            gtest_msg.value = "Expected: " #statement                             \
                              " throws an exception of type " #expected_exception \
                              ".\n  Actual: it throws a different type.";         \
            goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__);           \
          }                                                                       \
          if (!gtest_caught_expected) {                                           \
            gtest_msg.value = "Expected: " #statement                             \
                              " throws an exception of type " #expected_exception \
                              ".\n  Actual: it throws nothing.";                  \
            goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__);           \
          }                                                                       \
        } else /*NOLINT*/                                                         \
          GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__)                   \
              : fail(gtest_msg.value.c_str())
      

            Assignee:
            Guillaume Racicot
            Reporter:
            Billy Donahue
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: