diff --git a/docs/mockery/configuration.rst b/docs/mockery/configuration.rst index 3a89579cf..5c0bcfb5f 100644 --- a/docs/mockery/configuration.rst +++ b/docs/mockery/configuration.rst @@ -10,6 +10,8 @@ currently present include: * Option to allow/disallow the mocking of methods which do not actually exist fulfilled (i.e. unused) +* Option to allow/disallow the existence of default expectations defined with + quick definitions which are never fulfilled (i.e. unused) * Setter/Getter for added a parameter map for internal PHP class methods (``Reflection`` cannot detect these automatically) @@ -18,19 +20,23 @@ situations where this can lead to unintended consequences. The mocking of non-existent methods may allow mocks based on real classes/objects to fall out of sync with the actual implementations, especially when some degree of integration testing (testing of object wiring) is not being performed. +Allowing unfulfilled default expectations defined with quick definitions means +unnecessary mock expectations go unnoticed, cluttering up test code, and +potentially confusing test readers. -You may allow or disallow this behaviour (whether for whole test suites or -just select tests) by using the following call: +You may allow or disallow these behaviours (whether for whole test suites or +just select tests) by using one or both of the following two calls: .. code-block:: php \Mockery::getConfiguration()->allowMockingNonExistentMethods(bool); + \Mockery::getConfiguration()->allowMockingQuickDefaultExpectationMethodsUnnecessarily(bool); -Passing a true allows the behaviour, false disallows it. It takes effect -immediately until switched back. If the behaviour is detected when not allowed, -it will result in an Exception being thrown at that point. Note that disallowing -this behaviour should be carefully considered since it necessarily removes at -least some of Mockery's flexibility. +Passing a true allows the behaviour, false disallows it. Both take effect +immediately until switched back. In both cases, if either behaviour is detected +when not allowed, it will result in an Exception being thrown at that point. +Note that disallowing these behaviours should be carefully considered since they +necessarily remove at least some of Mockery's flexibility. The other two methods are: diff --git a/library/Mockery/Configuration.php b/library/Mockery/Configuration.php index 125f1541a..e3a5012ad 100644 --- a/library/Mockery/Configuration.php +++ b/library/Mockery/Configuration.php @@ -40,6 +40,16 @@ class Configuration */ protected $_allowMockingMethodsUnnecessarily = true; + /** + * Boolean assertion of whether we ignore unnecessary mocking of methods, + * for default expectations defined with quick definitions. i.e. when + * method default expectations are made and then never called. Essentially + * such expectations are not required and are just taking up test space. + * + * @var bool + */ + protected $_allowQuickMockingDefaultExpectationMethodsUnnecessarily = true; + /** * Parameter map for use with PHP internal classes. * @@ -103,6 +113,28 @@ public function mockingMethodsUnnecessarilyAllowed() return $this->_allowMockingMethodsUnnecessarily; } + /** + * Set boolean to allow/prevent unnecessary mocking of methods for default + * expectations defined in quick definitions. + * + * @param bool $flag + */ + public function allowMockingQuickDefaultExpectationMethodsUnnecessarily($flag = true) + { + $this->_allowQuickMockingDefaultExpectationMethodsUnnecessarily = (bool) $flag; + } + + /** + * Return flag indicating whether mocking non-existent methods for default + * expectations defined in quick definitions is allowed. + * + * @return bool + */ + public function mockingQuickDefaultExpectationMethodsUnnecessarilyAllowed() + { + return $this->_allowQuickMockingDefaultExpectationMethodsUnnecessarily; + } + /** * Set a parameter map (array of param signature strings) for the method * of an internal PHP class. diff --git a/library/Mockery/Container.php b/library/Mockery/Container.php index e50a15611..5b89e450a 100644 --- a/library/Mockery/Container.php +++ b/library/Mockery/Container.php @@ -233,7 +233,11 @@ public function mock(...$args) $mock->mockery_init($this, $config->getTargetObject(), $config->isInstanceMock()); if (!empty($quickdefs)) { - $mock->shouldReceive($quickdefs)->byDefault(); + if (\Mockery::getConfiguration()->mockingQuickDefaultExpectationMethodsUnnecessarilyAllowed()) { + $mock->shouldReceive($quickdefs)->byDefault(); + } else { + $mock->shouldReceive($quickdefs)->byDefault()->atLeast()->once(); + } } if (!empty($expectationClosure)) { $expectationClosure($mock); diff --git a/tests/Mockery/ExpectationTest.php b/tests/Mockery/ExpectationTest.php index fc2a7a3b5..2c5a6d5c9 100644 --- a/tests/Mockery/ExpectationTest.php +++ b/tests/Mockery/ExpectationTest.php @@ -1866,6 +1866,22 @@ public function testGlobalConfigMayForbidMockingNonExistentMethodsOnObjects() Mockery::close(); } + public function testGlobalConfigMayForbidMockingQuickDefaultExpectationMethodsUnnecessarily() + { + \Mockery::getConfiguration()->allowMockingQuickDefaultExpectationMethodsUnnecessarily(false); + mock(array('foo'=>1)); + $this->expectException(\Mockery\Exception\InvalidCountException::class); + Mockery::close(); + } + + public function testGlobalConfigMayAllowMockingQuickDefaultExpectationMethodsUnnecessarily() + { + \Mockery::getConfiguration()->allowMockingQuickDefaultExpectationMethodsUnnecessarily(true); + mock(array('foo'=>1)); + $this->expectNotToPerformAssertions(); + Mockery::close(); + } + public function testAnExampleWithSomeExpectationAmends() { $service = mock('MyService');