shmock
shmock copied to clipboard
Use dont_preserve_original_methods and order_matters together for ClassBuilderStaticClass yields unexpected result
Here is an example that illustrates the issue:
shmock_class( 'Box_Helper_URL', function ( $shmock /** @var Box_Helper_URL|\Shmock\ClassBuilderStaticClass $shmock */ ) { // Keep track of the order of calls made on this mock. $shmock->order_matters(); // Mock all methods, return null by default unless overwritten by the expectations below. $shmock->dont_preserve_original_methods(); $shmock->disable_original_constructor(); $mock = $shmock->url_is_box('ab.com'); /** @var $mock \Shmock\Spec */ $mock->return_value(true); } ); \Statics::overwrite('Box_Helper_URL', $mockBox_Helper_URL0); // Execute the method under test. $objectUnderTest = new \StaticsUsageExample(); $executionResult = $objectUnderTest->isBoxUrl('ab.com'); // Validate the execution result. $expected = true; $this->assertSame( $expected, $executionResult, 'Variable ( executionResult ) doesn\'t have the expected value.' ); ``` } } The test failed. The url_is_box call on the mock object returned null instead of true as I expected. # Here is my analysis of the issue: This is what I found that caused the failure: dont_preserve_original_methods calls $this->__call($method->getName(), [])->any()->return_null(); to overwrite the static method calls of the class being mocked. This has the same effect as specifying $shmock->url_is_box()->any()->return_value(null); in the mock object expectations. Since order_matter is set, in effect the expectation becomes that url_is_box will be called once first and return null and it should be called again and this time return true. This effect is not what I expected. And there is no documentation that I can find that describes this behavior. The non static class builder has a different implementation and doesn't seem to exhibit this behavior.