diff --git a/include/gmock/gmock-spec-builders.h b/include/gmock/gmock-spec-builders.h index c677333c..59f1d71e 100644 --- a/include/gmock/gmock-spec-builders.h +++ b/include/gmock/gmock-spec-builders.h @@ -66,6 +66,10 @@ #include #include +#if GTEST_HAS_EXCEPTIONS +# include // NOLINT +#endif + #include "gmock/gmock-actions.h" #include "gmock/gmock-cardinalities.h" #include "gmock/gmock-matchers.h" @@ -1425,10 +1429,12 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { return NULL; } - // Performs the default action of this mock function on the given arguments - // and returns the result. Asserts with a helpful call descrption if there is - // no valid return value. This method doesn't depend on the mutable state of - // this object, and thus can be called concurrently without locking. + // Performs the default action of this mock function on the given + // arguments and returns the result. Asserts (or throws if + // exceptions are enabled) with a helpful call descrption if there + // is no valid return value. This method doesn't depend on the + // mutable state of this object, and thus can be called concurrently + // without locking. // L = * Result PerformDefaultAction(const ArgumentTuple& args, const string& call_description) const { @@ -1437,9 +1443,16 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { if (spec != NULL) { return spec->GetAction().Perform(args); } - Assert(DefaultValue::Exists(), "", -1, - call_description + "\n The mock function has no default action " - "set, and its return type has no default value set."); + const string message = call_description + + "\n The mock function has no default action " + "set, and its return type has no default value set."; +#if GTEST_HAS_EXCEPTIONS + if (!DefaultValue::Exists()) { + throw std::runtime_error(message); + } +#else + Assert(DefaultValue::Exists(), "", -1, message); +#endif return DefaultValue::Get(); } diff --git a/test/gmock-actions_test.cc b/test/gmock-actions_test.cc index fd87c74c..1210d464 100644 --- a/test/gmock-actions_test.cc +++ b/test/gmock-actions_test.cc @@ -634,15 +634,19 @@ TEST(DoDefaultTest, ReturnsBuiltInDefaultValueByDefault) { EXPECT_EQ(0, mock.IntFunc(true)); } -// Tests that DoDefault() aborts the process when there is no built-in -// default value for the return type. +// Tests that DoDefault() throws (when exceptions are enabled) or aborts +// the process when there is no built-in default value for the return type. TEST(DoDefaultDeathTest, DiesForUnknowType) { MockClass mock; EXPECT_CALL(mock, Foo()) .WillRepeatedly(DoDefault()); +#if GTEST_HAS_EXCEPTIONS + EXPECT_ANY_THROW(mock.Foo()); +#else EXPECT_DEATH_IF_SUPPORTED({ mock.Foo(); }, ""); +#endif } // Tests that using DoDefault() inside a composite action leads to a diff --git a/test/gmock-spec-builders_test.cc b/test/gmock-spec-builders_test.cc index 0e2e0090..8a8632dc 100644 --- a/test/gmock-spec-builders_test.cc +++ b/test/gmock-spec-builders_test.cc @@ -1111,7 +1111,11 @@ TEST(UndefinedReturnValueTest, ReturnValueIsMandatory) { // TODO(wan@google.com): We should really verify the output message, // but we cannot yet due to that EXPECT_DEATH only captures stderr // while Google Mock logs to stdout. +#if GTEST_HAS_EXCEPTIONS + EXPECT_ANY_THROW(a.ReturnResult(1)); +#else EXPECT_DEATH_IF_SUPPORTED(a.ReturnResult(1), ""); +#endif } // Tests that an excessive call (one whose arguments match the @@ -1260,87 +1264,116 @@ TEST(SequenceTest, AnyOrderIsOkByDefault) { // Tests that the calls must be in strict order when a complete order // is specified. -TEST(SequenceTest, CallsMustBeInStrictOrderWhenSaidSo) { +TEST(SequenceTest, CallsMustBeInStrictOrderWhenSaidSo1) { MockA a; + ON_CALL(a, ReturnResult(_)) + .WillByDefault(Return(Result())); + Sequence s; - EXPECT_CALL(a, ReturnResult(1)) - .InSequence(s) - .WillOnce(Return(Result())); - + .InSequence(s); EXPECT_CALL(a, ReturnResult(2)) - .InSequence(s) - .WillOnce(Return(Result())); - + .InSequence(s); EXPECT_CALL(a, ReturnResult(3)) - .InSequence(s) - .WillOnce(Return(Result())); - - EXPECT_DEATH_IF_SUPPORTED({ - a.ReturnResult(1); - a.ReturnResult(3); - a.ReturnResult(2); - }, ""); - - EXPECT_DEATH_IF_SUPPORTED({ - a.ReturnResult(2); - a.ReturnResult(1); - a.ReturnResult(3); - }, ""); + .InSequence(s); a.ReturnResult(1); + + // May only be called after a.ReturnResult(2). + EXPECT_NONFATAL_FAILURE(a.ReturnResult(3), "Unexpected mock function call"); + a.ReturnResult(2); a.ReturnResult(3); } -// Tests specifying a DAG using multiple sequences. -TEST(SequenceTest, CallsMustConformToSpecifiedDag) { +// Tests that the calls must be in strict order when a complete order +// is specified. +TEST(SequenceTest, CallsMustBeInStrictOrderWhenSaidSo2) { MockA a; - MockB b; - Sequence x, y; + ON_CALL(a, ReturnResult(_)) + .WillByDefault(Return(Result())); + Sequence s; EXPECT_CALL(a, ReturnResult(1)) - .InSequence(x) - .WillOnce(Return(Result())); - - EXPECT_CALL(b, DoB()) - .Times(2) - .InSequence(y); - + .InSequence(s); EXPECT_CALL(a, ReturnResult(2)) - .InSequence(x, y) - .WillRepeatedly(Return(Result())); + .InSequence(s); - EXPECT_CALL(a, ReturnResult(3)) - .InSequence(x) - .WillOnce(Return(Result())); + // May only be called after a.ReturnResult(1). + EXPECT_NONFATAL_FAILURE(a.ReturnResult(2), "Unexpected mock function call"); - EXPECT_DEATH_IF_SUPPORTED({ - a.ReturnResult(1); - b.DoB(); - a.ReturnResult(2); - }, ""); - - EXPECT_DEATH_IF_SUPPORTED({ - a.ReturnResult(2); - }, ""); - - EXPECT_DEATH_IF_SUPPORTED({ - a.ReturnResult(3); - }, ""); - - EXPECT_DEATH_IF_SUPPORTED({ - a.ReturnResult(1); - b.DoB(); - b.DoB(); - a.ReturnResult(3); - a.ReturnResult(2); - }, ""); - - b.DoB(); a.ReturnResult(1); - b.DoB(); - a.ReturnResult(3); + a.ReturnResult(2); +} + +// Tests specifying a DAG using multiple sequences. +class PartialOrderTest : public testing::Test { + protected: + PartialOrderTest() { + ON_CALL(a_, ReturnResult(_)) + .WillByDefault(Return(Result())); + + // Specifies this partial ordering: + // + // a.ReturnResult(1) ==> + // a.ReturnResult(2) * n ==> a.ReturnResult(3) + // b.DoB() * 2 ==> + Sequence x, y; + EXPECT_CALL(a_, ReturnResult(1)) + .InSequence(x); + EXPECT_CALL(b_, DoB()) + .Times(2) + .InSequence(y); + EXPECT_CALL(a_, ReturnResult(2)) + .Times(AnyNumber()) + .InSequence(x, y); + EXPECT_CALL(a_, ReturnResult(3)) + .InSequence(x); + } + + MockA a_; + MockB b_; +}; + +TEST_F(PartialOrderTest, CallsMustConformToSpecifiedDag1) { + a_.ReturnResult(1); + b_.DoB(); + + // May only be called after the second DoB(). + EXPECT_NONFATAL_FAILURE(a_.ReturnResult(2), "Unexpected mock function call"); + + b_.DoB(); + a_.ReturnResult(3); +} + +TEST_F(PartialOrderTest, CallsMustConformToSpecifiedDag2) { + // May only be called after ReturnResult(1). + EXPECT_NONFATAL_FAILURE(a_.ReturnResult(2), "Unexpected mock function call"); + + a_.ReturnResult(1); + b_.DoB(); + b_.DoB(); + a_.ReturnResult(3); +} + +TEST_F(PartialOrderTest, CallsMustConformToSpecifiedDag3) { + // May only be called last. + EXPECT_NONFATAL_FAILURE(a_.ReturnResult(3), "Unexpected mock function call"); + + a_.ReturnResult(1); + b_.DoB(); + b_.DoB(); + a_.ReturnResult(3); +} + +TEST_F(PartialOrderTest, CallsMustConformToSpecifiedDag4) { + a_.ReturnResult(1); + b_.DoB(); + b_.DoB(); + a_.ReturnResult(3); + + // May only be called before ReturnResult(3). + EXPECT_NONFATAL_FAILURE(a_.ReturnResult(2), "Unexpected mock function call"); } TEST(SequenceTest, Retirement) { @@ -1530,71 +1563,112 @@ TEST(AfterTest, SucceedsWhenTotalOrderIsSatisfied) { a.DoA(2); } -// Calls must be in strict order when specified so. -TEST(AfterDeathTest, CallsMustBeInStrictOrderWhenSpecifiedSo) { +// Calls must be in strict order when specified so using .After(). +TEST(AfterTest, CallsMustBeInStrictOrderWhenSpecifiedSo1) { MockA a; MockB b; + + // Define ordering: + // a.DoA(1) ==> b.DoB() ==> a.DoA(2) + Expectation e1 = EXPECT_CALL(a, DoA(1)); + Expectation e2 = EXPECT_CALL(b, DoB()) + .After(e1); + EXPECT_CALL(a, DoA(2)) + .After(e2); + + a.DoA(1); + + // May only be called after DoB(). + EXPECT_NONFATAL_FAILURE(a.DoA(2), "Unexpected mock function call"); + + b.DoB(); + a.DoA(2); +} + +// Calls must be in strict order when specified so using .After(). +TEST(AfterTest, CallsMustBeInStrictOrderWhenSpecifiedSo2) { + MockA a; + MockB b; + + // Define ordering: + // a.DoA(1) ==> b.DoB() * 2 ==> a.DoA(2) Expectation e1 = EXPECT_CALL(a, DoA(1)); Expectation e2 = EXPECT_CALL(b, DoB()) .Times(2) .After(e1); - EXPECT_CALL(a, ReturnResult(2)) - .After(e2) - .WillOnce(Return(Result())); + EXPECT_CALL(a, DoA(2)) + .After(e2); a.DoA(1); - // If a call to ReturnResult() violates the specified order, no - // matching expectation will be found, and thus the default action - // will be done. Since the return type of ReturnResult() is not a - // built-in type, gmock won't know what to return and will thus - // abort the program. Therefore a death test can tell us whether - // gmock catches the order violation correctly. - // - // gtest and gmock print messages to stdout, which isn't captured by - // death tests. Therefore we have to match with an empty regular - // expression in all the EXPECT_DEATH()s. - EXPECT_DEATH_IF_SUPPORTED(a.ReturnResult(2), ""); + b.DoB(); + + // May only be called after the second DoB(). + EXPECT_NONFATAL_FAILURE(a.DoA(2), "Unexpected mock function call"); b.DoB(); - EXPECT_DEATH_IF_SUPPORTED(a.ReturnResult(2), ""); - - b.DoB(); - a.ReturnResult(2); + a.DoA(2); } // Calls must satisfy the partial order when specified so. -TEST(AfterDeathTest, CallsMustSatisfyPartialOrderWhenSpecifiedSo) { +TEST(AfterTest, CallsMustSatisfyPartialOrderWhenSpecifiedSo) { MockA a; + ON_CALL(a, ReturnResult(_)) + .WillByDefault(Return(Result())); + + // Define ordering: + // a.DoA(1) ==> + // a.DoA(2) ==> a.ReturnResult(3) Expectation e = EXPECT_CALL(a, DoA(1)); const ExpectationSet es = EXPECT_CALL(a, DoA(2)); EXPECT_CALL(a, ReturnResult(3)) - .After(e, es) - .WillOnce(Return(Result())); + .After(e, es); - EXPECT_DEATH_IF_SUPPORTED(a.ReturnResult(3), ""); + // May only be called last. + EXPECT_NONFATAL_FAILURE(a.ReturnResult(3), "Unexpected mock function call"); a.DoA(2); - EXPECT_DEATH_IF_SUPPORTED(a.ReturnResult(3), ""); - a.DoA(1); a.ReturnResult(3); } +// Calls must satisfy the partial order when specified so. +TEST(AfterTest, CallsMustSatisfyPartialOrderWhenSpecifiedSo2) { + MockA a; + + // Define ordering: + // a.DoA(1) ==> + // a.DoA(2) ==> a.DoA(3) + Expectation e = EXPECT_CALL(a, DoA(1)); + const ExpectationSet es = EXPECT_CALL(a, DoA(2)); + EXPECT_CALL(a, DoA(3)) + .After(e, es); + + a.DoA(2); + + // May only be called last. + EXPECT_NONFATAL_FAILURE(a.DoA(3), "Unexpected mock function call"); + + a.DoA(1); + a.DoA(3); +} + // .After() can be combined with .InSequence(). -TEST(AfterDeathTest, CanBeUsedWithInSequence) { +TEST(AfterTest, CanBeUsedWithInSequence) { MockA a; Sequence s; Expectation e = EXPECT_CALL(a, DoA(1)); EXPECT_CALL(a, DoA(2)).InSequence(s); - EXPECT_CALL(a, ReturnResult(3)) - .InSequence(s).After(e) - .WillOnce(Return(Result())); + EXPECT_CALL(a, DoA(3)) + .InSequence(s) + .After(e); a.DoA(1); - EXPECT_DEATH_IF_SUPPORTED(a.ReturnResult(3), ""); + + // May only be after DoA(2). + EXPECT_NONFATAL_FAILURE(a.DoA(3), "Unexpected mock function call"); a.DoA(2); - a.ReturnResult(3); + a.DoA(3); } // .After() can be called multiple times. @@ -1636,17 +1710,24 @@ TEST(AfterTest, AcceptsUpToFiveArguments) { // .After() allows input to contain duplicated Expectations. TEST(AfterTest, AcceptsDuplicatedInput) { MockA a; + ON_CALL(a, ReturnResult(_)) + .WillByDefault(Return(Result())); + + // Define ordering: + // DoA(1) ==> + // DoA(2) ==> ReturnResult(3) Expectation e1 = EXPECT_CALL(a, DoA(1)); Expectation e2 = EXPECT_CALL(a, DoA(2)); ExpectationSet es; es += e1; es += e2; EXPECT_CALL(a, ReturnResult(3)) - .After(e1, e2, es, e1) - .WillOnce(Return(Result())); + .After(e1, e2, es, e1); a.DoA(1); - EXPECT_DEATH_IF_SUPPORTED(a.ReturnResult(3), ""); + + // May only be after DoA(2). + EXPECT_NONFATAL_FAILURE(a.ReturnResult(3), "Unexpected mock function call"); a.DoA(2); a.ReturnResult(3); diff --git a/test/gmock_ex_test.cc b/test/gmock_ex_test.cc new file mode 100644 index 00000000..a5a8a421 --- /dev/null +++ b/test/gmock_ex_test.cc @@ -0,0 +1,78 @@ +// Copyright 2013, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + +// Tests Google Mock's functionality that depends on exceptions. + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace { + +using testing::HasSubstr; +using testing::internal::GoogleTestFailureException; + +// A user-defined class. +class Something {}; + +class MockFoo { + public: + // A mock method that returns a user-defined type. Google Mock + // doesn't know what the default value for this type is. + MOCK_METHOD0(GetSomething, Something()); +}; + +#if GTEST_HAS_EXCEPTIONS + +TEST(DefaultValueTest, ThrowsRuntimeErrorWhenNoDefaultValue) { + MockFoo mock; + try { + // No expectation is set on this method, so Google Mock must + // return the default value. However, since Google Mock knows + // nothing about the return type, it doesn't know what to return, + // and has to throw (when exceptions are enabled) or abort + // (otherwise). + mock.GetSomething(); + FAIL() << "GetSomething()'s return type has no default value, " + << "so Google Mock should have thrown."; + } catch (const GoogleTestFailureException& /* unused */) { + FAIL() << "Google Test does not try to catch an exception of type " + << "GoogleTestFailureException, which is used for reporting " + << "a failure to other testing frameworks. Google Mock should " + << "not throw a GoogleTestFailureException as it will kill the " + << "entire test program instead of just the current TEST."; + } catch (const std::exception& ex) { + EXPECT_THAT(ex.what(), HasSubstr("has no default value")); + } +} + +#endif + +} // unnamed namespace