diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h index f20258bc..fab99933 100644 --- a/googlemock/include/gmock/gmock-actions.h +++ b/googlemock/include/gmock/gmock-actions.h @@ -135,6 +135,7 @@ #endif #include +#include #include #include #include @@ -1746,6 +1747,13 @@ struct ThrowAction { return [copy](Args...) -> R { throw copy; }; } }; +struct RethrowAction { + std::exception_ptr exception; + template + operator Action() const { // NOLINT + return [ex = exception](Args...) -> R { std::rethrow_exception(ex); }; + } +}; #endif // GTEST_HAS_EXCEPTIONS } // namespace internal @@ -2062,13 +2070,23 @@ internal::ReturnPointeeAction ReturnPointee(Ptr pointer) { return {pointer}; } -// Action Throw(exception) can be used in a mock function of any type -// to throw the given exception. Any copyable value can be thrown. #if GTEST_HAS_EXCEPTIONS +// Action Throw(exception) can be used in a mock function of any type +// to throw the given exception. Any copyable value can be thrown, +// except for std::exception_ptr, which is likely a mistake if +// thrown directly. template -internal::ThrowAction::type> Throw(T&& exception) { +typename std::enable_if< + !std::is_base_of::type>::value, + internal::ThrowAction::type>>::type +Throw(T&& exception) { return {std::forward(exception)}; } +// Action Rethrow(exception_ptr) can be used in a mock function of any type +// to rethrow any exception_ptr. Note that the same object is thrown each time. +inline internal::RethrowAction Rethrow(std::exception_ptr exception) { + return {std::move(exception)}; +} #endif // GTEST_HAS_EXCEPTIONS namespace internal { diff --git a/googlemock/test/gmock_link_test.h b/googlemock/test/gmock_link_test.h index db11c2d2..cf0a985b 100644 --- a/googlemock/test/gmock_link_test.h +++ b/googlemock/test/gmock_link_test.h @@ -187,6 +187,7 @@ using testing::SetErrnoAndReturn; #if GTEST_HAS_EXCEPTIONS using testing::Throw; +using testing::Rethrow; #endif using testing::ContainsRegex; @@ -416,6 +417,14 @@ TEST(LinkTest, TestThrow) { EXPECT_CALL(mock, VoidFromString(_)).WillOnce(Throw(42)); EXPECT_THROW(mock.VoidFromString(nullptr), int); } +// Tests the linkage of the Rethrow action. +TEST(LinkTest, TestRethrow) { + Mock mock; + + EXPECT_CALL(mock, VoidFromString(_)) + .WillOnce(Rethrow(std::make_exception_ptr(42))); + EXPECT_THROW(mock.VoidFromString(nullptr), int); +} #endif // GTEST_HAS_EXCEPTIONS // The ACTION*() macros trigger warning C4100 (unreferenced formal