phpunit
phpunit copied to clipboard
MockObject can be used to test consecutive method calls.
Allow mock object to be used to mock methods with same name, but with different parameters. Addresses #4255 and #4026.
This can be easily ported to 9.6. Just let me know if i need to target 9.6.
Codecov Report
Merging #5203 (99dd3c2) into main (c90bc5b) will decrease coverage by
0.09%
. The diff coverage is50.98%
.
@@ Coverage Diff @@
## main #5203 +/- ##
============================================
- Coverage 81.28% 81.19% -0.09%
- Complexity 5844 5866 +22
============================================
Files 629 629
Lines 18516 18561 +45
============================================
+ Hits 15051 15071 +20
- Misses 3465 3490 +25
Impacted Files | Coverage Δ | |
---|---|---|
src/Framework/MockObject/Rule/AnyParameters.php | 25.00% <0.00%> (-8.34%) |
:arrow_down: |
src/Framework/MockObject/Matcher.php | 54.09% <27.27%> (-5.91%) |
:arrow_down: |
src/Framework/MockObject/Rule/InvocationOrder.php | 69.23% <50.00%> (-8.55%) |
:arrow_down: |
src/Framework/MockObject/Rule/Parameters.php | 78.94% <66.66%> (-5.37%) |
:arrow_down: |
.../Framework/MockObject/Builder/InvocationMocker.php | 92.70% <90.90%> (-0.24%) |
:arrow_down: |
:mega: We’re building smart automated test selection to slash your CI/CD build times. Learn more
This can be easily ported to 9.6. Just let me know if i need to target 9.6.
PHPUnit 9 is closed for new functionality, the main
target is correct.
@sebastianbergmann What's the plan with this PR? Is it gonna be merged anytime soon? It would greatly help our migration from 9.6 to 10.
I did not have time to review this yet. Please note that by now I am very reluctant when it comes to add new functionality to test doubles.
It would help if you could provide real world use cases for the functionality you propose. Tests for test double functionality are usually not really representative and are not helpful for understanding what the functionality they test should be used and how.
Usually this is used to test consecutive calls to the same object.
For example the call that depends on a condition:
$sender->sendMoney($user, $amount);
if ($user->hasParent()) {
$sender->sendMoney($user->getParent(), $amount * 0.2);
}
The test double of the $sender
have 2 test cases:
-
testUserHaveNoParent
with$sender
sends$amount
to$user
once. -
testUserHaveParent
with$sender
sends$amount
to$user
once and then sends$amount * 0.2
to user's parent.
Or code that depends on the order:
interface Stack
{
public function handle(Handler $handler): void
}
class Forward implements Stack
{
public function handle(Handler $handler): void
{
for($i=0;$i<count($this->events);$i++) {
$handler->handle($this->events[$i]);
}
}
}
class Backward implements Stack
class Random implements Stack
class Odd implements Stack
....
The test case for each of the classes will check the order in which the event was handled.
In other words when the double is expected to call same method several times with different arguments and/or returns different value depending on arguments.
For more real world use cases you can search github and find PRs like this: https://github.com/symfony/symfony/pull/49621/files https://github.com/doctrine/orm/pull/10501/files
The current PR provides a way to remove the custom code and do it in the standardized way with PHPUnit MockObject API like it was with deprecated withConsecutive
, but addressing mentioned issues in the PR description.
@biozshock
Can you share how you would implement test cases for the examples that you shared in https://github.com/sebastianbergmann/phpunit/pull/5203#issuecomment-1479101454
- with the current functionality in
phpunit/phpunit
and - with the functionality you propose in this pull request
?
@localheinz Sure. Something along these lines:
class ForwardTest
{
public function testOld(): void
{
$handler = $this->createMock(Handler::class);
$handler->method('handle')
->withConsecutive($event1, $event2)
->willReturnOnConsecutiveCalls($return1, $return2);
$forward = new Forward();
$forward->handle($handle);
}
public function testNew(): void
{
$handler = $this->createMock(Handler::class);
$handler->expects(self::once())
->method('handle')
->with($event1)
->willReturn($return1)
->andThen(self:once())
->method('handle')
->with($event2)
->willReturn($return2);
$forward = new Forward();
$forward->handle($handle);
}
}
Hello everyone, Any updates or progress here?
@localheinz Has there maybe been any status update in regards to this PR?
Thank you for your contribution. I appreciate the time you invested in preparing this pull request. However, I have decided not to merge it.
Hello @sebastianbergmann , do you know if there's any plan on the roadmap to include this option for future releases? Thanks in advance!