| Q |
A |
| PHPUnit version |
12.1.0 |
| PHP version |
8.4.3 |
| Installation Method |
Composer |
Summary
The handling of default values in willReturnMap doesn't seem to take into account that parameters and/or default values may be null.
Current behavior
- Omitting a default null parameter in
willReturnMap does not work and causes the mapping to never match (see methodNullDefault tests below)
- Omitting a default non-null parameter does work, however doing so breaks the handling of other null parameters, even without default values (see
methodStringDefault tests below)
Therefore the only way to get the tests to pass is to provide the full set of parameters.
How to reproduce
<?php
namespace App;
interface SomeInterface
{
public function methodNullDefault(?string $param, ?string $nullDefault = null): string;
public function methodStringDefault(?string $param, ?string $stringDefault = 'something'): string;
}
<?php
use App\SomeInterface;
use PHPUnit\Framework\TestCase;
class SomeInterfaceTest extends TestCase
{
public function testMethodNullDefaultPasses(): void
{
$mock = $this->createMock(SomeInterface::class);
$mock->method('methodNullDefault')->willReturnMap([
['A', null, 'ret'],
]);
self::assertSame('ret', $mock->methodNullDefault('A'));
}
public function testMethodNullDefaultFails(): void
{
$mock = $this->createMock(SomeInterface::class);
$mock->method('methodNullDefault')->willReturnMap([
['A', 'ret'],
]);
self::assertSame('ret', $mock->methodNullDefault('A'));
}
public function testMethodStringDefaultPasses(): void
{
$mock = $this->createMock(SomeInterface::class);
$mock->method('methodStringDefault')->willReturnMap([
['A', 'ret'],
]);
self::assertSame('ret', $mock->methodStringDefault('A'));
}
public function testMethodStringDefaultFails(): void
{
$mock = $this->createMock(SomeInterface::class);
$mock->method('methodStringDefault')->willReturnMap([
[null, 'ret'],
]);
self::assertSame('ret', $mock->methodStringDefault(null));
}
}
Expected behavior
All of the above tests pass.
I believe this is caused by the two isset calls in
|
if (isset($mapping[$i])) { |
which I would guess should be
array_key_exists instead.
Output of composer info | sort
myclabs/deep-copy 1.13.0 Create deep copies (clones) of your objects
nikic/php-parser 5.4.0 A PHP parser written in PHP
phar-io/manifest 2.0.4 Component for reading phar.io manifest information from a PHP Archive (PHAR)
phar-io/version 3.2.1 Library for handling version information and constraints
phpunit/php-code-coverage 12.1.2 Library that provides collection, processing, and rendering functionality for PHP code coverage information.
phpunit/php-file-iterator 6.0.0 FilterIterator implementation that filters files based on a list of suffixes.
phpunit/php-invoker 6.0.0 Invoke callables with a timeout
phpunit/php-text-template 5.0.0 Simple template engine.
phpunit/php-timer 8.0.0 Utility class for timing
phpunit/phpunit 12.1.0 The PHP Unit Testing framework.
sebastian/cli-parser 4.0.0 Library for parsing CLI options
sebastian/comparator 7.0.1 Provides the functionality to compare PHP values for equality
sebastian/complexity 5.0.0 Library for calculating the complexity of PHP code units
sebastian/diff 7.0.0 Diff implementation
sebastian/environment 8.0.0 Provides functionality to handle HHVM/PHP environments
sebastian/exporter 7.0.0 Provides the functionality to export PHP variables for visualization
sebastian/global-state 8.0.0 Snapshotting of global state
sebastian/lines-of-code 4.0.0 Library for counting the lines of code in PHP source code
sebastian/object-enumerator 7.0.0 Traverses array structures and object graphs to enumerate all referenced objects
sebastian/object-reflector 5.0.0 Allows reflection of object attributes, including inherited and non-public ones
sebastian/recursion-context 7.0.0 Provides functionality to recursively process PHP variables
sebastian/type 6.0.2 Collection of value objects that represent the types of the PHP type system
sebastian/version 6.0.0 Library that helps with managing the version number of Git-hosted PHP projects
staabm/side-effects-detector 1.0.5 A static analysis tool to detect side effects in PHP code
theseer/tokenizer 1.2.3 A small library for converting tokenized PHP source code into XML and potentially other formats
Summary
The handling of default values in
willReturnMapdoesn't seem to take into account that parameters and/or default values may be null.Current behavior
willReturnMapdoes not work and causes the mapping to never match (seemethodNullDefaulttests below)methodStringDefaulttests below)Therefore the only way to get the tests to pass is to provide the full set of parameters.
How to reproduce
Expected behavior
All of the above tests pass.
I believe this is caused by the two
issetcalls inphpunit/src/Framework/MockObject/Runtime/InvocationStubberImplementation.php
Line 221 in cf54f48
array_key_existsinstead.Output of
composer info | sort