mirror of
https://github.com/google/googletest.git
synced 2025-01-14 00:20:57 +08:00
Googletest export
Fixing exception-safety bug in googletest. Previously, if an exception was thrown during a call to a mock that would have triggered an error, the error was discarded. Fixes #2890 PiperOrigin-RevId: 325017806
This commit is contained in:
parent
5a5caab358
commit
d0de618a58
@ -433,10 +433,10 @@ UntypedActionResultHolderBase* UntypedFunctionMockerBase::UntypedInvokeWith(
|
||||
|
||||
// The UntypedFindMatchingExpectation() function acquires and
|
||||
// releases g_gmock_mutex.
|
||||
|
||||
const ExpectationBase* const untyped_expectation =
|
||||
this->UntypedFindMatchingExpectation(
|
||||
untyped_args, &untyped_action, &is_excessive,
|
||||
&ss, &why);
|
||||
this->UntypedFindMatchingExpectation(untyped_args, &untyped_action,
|
||||
&is_excessive, &ss, &why);
|
||||
const bool found = untyped_expectation != nullptr;
|
||||
|
||||
// True if and only if we need to print the call's arguments
|
||||
@ -461,26 +461,42 @@ UntypedActionResultHolderBase* UntypedFunctionMockerBase::UntypedInvokeWith(
|
||||
untyped_expectation->DescribeLocationTo(&loc);
|
||||
}
|
||||
|
||||
UntypedActionResultHolderBase* const result =
|
||||
untyped_action == nullptr
|
||||
? this->UntypedPerformDefaultAction(untyped_args, ss.str())
|
||||
: this->UntypedPerformAction(untyped_action, untyped_args);
|
||||
if (result != nullptr) result->PrintAsActionResult(&ss);
|
||||
ss << "\n" << why.str();
|
||||
UntypedActionResultHolderBase* result = nullptr;
|
||||
|
||||
if (!found) {
|
||||
// No expectation matches this call - reports a failure.
|
||||
Expect(false, nullptr, -1, ss.str());
|
||||
} else if (is_excessive) {
|
||||
// We had an upper-bound violation and the failure message is in ss.
|
||||
Expect(false, untyped_expectation->file(),
|
||||
untyped_expectation->line(), ss.str());
|
||||
} else {
|
||||
// We had an expected call and the matching expectation is
|
||||
// described in ss.
|
||||
Log(kInfo, loc.str() + ss.str(), 2);
|
||||
auto perform_action = [&] {
|
||||
return untyped_action == nullptr
|
||||
? this->UntypedPerformDefaultAction(untyped_args, ss.str())
|
||||
: this->UntypedPerformAction(untyped_action, untyped_args);
|
||||
};
|
||||
auto handle_failures = [&] {
|
||||
ss << "\n" << why.str();
|
||||
|
||||
if (!found) {
|
||||
// No expectation matches this call - reports a failure.
|
||||
Expect(false, nullptr, -1, ss.str());
|
||||
} else if (is_excessive) {
|
||||
// We had an upper-bound violation and the failure message is in ss.
|
||||
Expect(false, untyped_expectation->file(), untyped_expectation->line(),
|
||||
ss.str());
|
||||
} else {
|
||||
// We had an expected call and the matching expectation is
|
||||
// described in ss.
|
||||
Log(kInfo, loc.str() + ss.str(), 2);
|
||||
}
|
||||
};
|
||||
#if GTEST_HAS_EXCEPTIONS
|
||||
try {
|
||||
result = perform_action();
|
||||
} catch (...) {
|
||||
handle_failures();
|
||||
throw;
|
||||
}
|
||||
#else
|
||||
result = perform_action();
|
||||
#endif
|
||||
|
||||
if (result != nullptr) result->PrintAsActionResult(&ss);
|
||||
handle_failures();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,9 @@
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest-spi.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace testing {
|
||||
@ -604,6 +606,33 @@ TEST(ThrowActionTest, ThrowsGivenExceptionInNullaryFunction) {
|
||||
EXPECT_THROW(a.Perform(std::make_tuple()), MyException);
|
||||
}
|
||||
|
||||
class Object {
|
||||
public:
|
||||
virtual ~Object() {}
|
||||
virtual void Func() {}
|
||||
};
|
||||
|
||||
class MockObject : public Object {
|
||||
public:
|
||||
~MockObject() override {}
|
||||
MOCK_METHOD(void, Func, (), (override));
|
||||
};
|
||||
|
||||
TEST(ThrowActionTest, Times0) {
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
[] {
|
||||
try {
|
||||
MockObject m;
|
||||
ON_CALL(m, Func()).WillByDefault([] { throw "something"; });
|
||||
EXPECT_CALL(m, Func()).Times(0);
|
||||
m.Func();
|
||||
} catch (...) {
|
||||
// Exception is caught but Times(0) still triggers a failure.
|
||||
}
|
||||
}(),
|
||||
"");
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_EXCEPTIONS
|
||||
|
||||
// Tests that SetArrayArgument<N>(first, last) sets the elements of the array
|
||||
|
Loading…
x
Reference in New Issue
Block a user