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.
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.