It seems that I am not the only one facing this issue. Maybe a bit more of information on the documentation could help other not loosing 3h. Something like : be carefull when mocking method with a default argument. You must add them in the map in order to work.
I have add at the end the solution.
Initial question:
I am trying to use returnValueMap starting with the doc example, I only change the class I am mocking from stdClass to Symfony\Component\DependencyInjection\ContainerInterface and it stop working, the call to the method now allways return null instead of content of the map.
Here the minimal code showing this error.
<?php
namespace Tests\SomeBundle\Controller;
use Symfony\Component\DependencyInjection\ContainerInterface;
use PHPUnit\Framework\TestCase;
class SomeTest extends TestCase
{
public function testReturnValueMapStub()
{
// Create a stub for the SomeClass class.
//$stub = $this->getMockBuilder('stdClass')
$stub = $this->getMockBuilder(ContainerInterface::class)
->setMethods(['get','set','has','initialized','getParameter','hasParameter','setParameter'])
->getMock();
// Create a map of arguments to return values.
$map = [
['a', 'd'],
['e', 'h']
];
// Configure the stub.
$stub->method('get')->will($this->returnValueMap($map));
// $stub->doSomething() returns different values depending on
// the provided arguments.
$this->assertEquals('d', $stub->get('a'));
$this->assertEquals('h', $stub->get('e'));
}
}
You can comment/uncomment the two line calling getMockBuilder to see that the responsible is ContainerInterface.
Here the beginning the mapped interface
<?php
namespace Symfony\Component\DependencyInjection;
use Psr\Container\ContainerInterface as PsrContainerInterface;
interface ContainerInterface extends PsrContainerInterface
{
const EXCEPTION_ON_INVALID_REFERENCE = 1;
const NULL_ON_INVALID_REFERENCE = 2;
const IGNORE_ON_INVALID_REFERENCE = 3;
const IGNORE_ON_UNINITIALIZED_REFERENCE = 4;
public function set($id, $service);
public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE);
...
The code working
The issue was : the get need 2 arguments and the second one is facultative, so easily forgotten. It is required to put it on the map. It was working with stdClass because php had no idea this method required 2 arguments. Using the interface it know and map the first two element of the map has method argument, thus nothing is left to be return.
public function testReturnValueMapStub()
{
// Create a stub for the SomeClass class.
//$stub = $this->getMockBuilder('stdClass')
$stub = $this->getMockBuilder(ContainerInterface::class)
->setMethods(['get','set','has','initialized','getParameter','hasParameter','setParameter'])
->getMock();
// Create a map of arguments to return values. with default argument
$map = [
['a','c', 'd'],
['e','d','h']
];
// Configure the stub.
$stub->method('get')->will($this->returnValueMap($map));
// $stub->doSomething() returns different values depending on
// the provided arguments.
$this->assertEquals('d', $stub->get('a','c'));
$this->assertEquals('h', $stub->get('e','d'));
}
Return of command composer info | sort
composer/ca-bundle 1.1.3 Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bu...
doctrine/annotations v1.6.0 Docblock Annotations Parser
doctrine/cache v1.8.0 Caching library offering an object-oriented API for many cache backends
doctrine/collections v1.5.0 Collections Abstraction library
doctrine/common v2.10.0 PHP Doctrine Common project is a library that provides additional functionality that other...
doctrine/data-fixtures v1.3.1 Data Fixtures for all Doctrine Object Managers
doctrine/dbal v2.9.2 Powerful PHP database abstraction layer (DBAL) with many features for database schema intr...
doctrine/doctrine-bundle 1.10.1 Symfony DoctrineBundle
doctrine/doctrine-cache-bundle 1.3.5 Symfony Bundle for Doctrine Cache
doctrine/doctrine-fixtures-bundle v2.4.1 Symfony DoctrineFixturesBundle
doctrine/event-manager v1.0.0 Doctrine Event Manager component
doctrine/inflector v1.3.0 Common String Manipulations with regard to casing and singular/plural rules.
doctrine/instantiator 1.1.0 A small, lightweight utility to instantiate objects in PHP without invoking their construc...
doctrine/lexer v1.0.1 Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.
doctrine/orm v2.6.3 Object-Relational-Mapper for PHP
doctrine/persistence v1.1.0 The Doctrine Persistence project is a set of shared interfaces and functionality that the ...
doctrine/reflection v1.0.0 Doctrine Reflection component
fig/link-util 1.0.0 Common utility implementations for HTTP links
incenteev/composer-parameter-handler v2.1.3 Composer script handling your ignored parameter file
jdorn/sql-formatter v1.2.17 a PHP SQL highlighting library
jms/metadata 1.7.0 Class/method/property metadata management in PHP
jms/parser-lib 1.0.0 A library for easily creating recursive-descent parsers.
jms/serializer 1.13.0 Library for (de-)serializing data of any complexity; supports XML, JSON, and YAML.
jms/serializer-bundle 2.4.3 Allows you to easily serialize, and deserialize data of any complexity
monolog/monolog 1.24.0 Sends your logs to files, sockets, inboxes, databases and various web services
myclabs/deep-copy 1.8.1 Create deep copies (clones) of your objects
openlss/lib-array2xml 0.0.10 Array2XML conversion library credit to lalit.org
paragonie/random_compat v9.99.99 PHP 5.x polyfill for random_bytes() and random_int() from PHP 7
phar-io/manifest 1.0.3 Component for reading phar.io manifest information from a PHP Archive (PHAR)
phar-io/version 2.0.1 Library for handling version information and constraints
phpcollection/phpcollection 0.5.0 General-Purpose Collection Library for PHP
phpdocumentor/reflection-common 1.0.1 Common reflection classes used by phpdocumentor to reflect the code structure
phpdocumentor/reflection-docblock 4.3.0 With this component, a library can provide support for annotations via DocBlocks or otherw...
phpdocumentor/type-resolver 0.4.0
phpoption/phpoption 1.5.0 Option Type for PHP
phpspec/prophecy 1.8.0 Highly opinionated mocking framework for PHP 5.3+
phpunit/php-code-coverage 6.1.4 Library that provides collection, processing, and rendering functionality for PHP code cov...
phpunit/php-file-iterator 2.0.2 FilterIterator implementation that filters files based on a list of suffixes.
phpunit/php-text-template 1.2.1 Simple template engine.
phpunit/php-timer 2.0.0 Utility class for timing
phpunit/php-token-stream 3.0.1 Wrapper around PHP's tokenizer extension.
phpunit/phpunit 7.5.2 The PHP Unit Testing framework.
psr/cache 1.0.1 Common interface for caching libraries
psr/container 1.0.0 Common Container Interface (PHP FIG PSR-11)
psr/link 1.0.0 Common interfaces for HTTP links
psr/log 1.1.0 Common interface for logging libraries
psr/simple-cache 1.0.1 Common interfaces for simple cachingas Doctrine field type.
sebastian/code-unit-reverse-lookup 1.0.1 Looks up which function or method a line of code belongs to
sebastian/comparator 3.0.2 Provides the functionality to compare PHP values for equality
sebastian/diff 3.0.1 Diff implementation
sebastian/environment 4.0.1 Provides functionality to handle HHVM/PHP environments
sebastian/exporter 3.1.0 Provides the functionality to export PHP variables for visualization
sebastian/global-state 2.0.0 Snapshotting of global state
sebastian/object-enumerator 3.0.3 Traverses array structures and object graphs to enumerate all referenced objects
sebastian/object-reflector 1.1.1 Allows reflection of object attributes, including inherited and non-public ones
sebastian/recursion-context 3.0.0 Provides functionality to recursively process PHP variables
sebastian/resource-operations 2.0.1 Provides a list of PHP built-in functions that operate on resources
sebastian/version 2.0.1 Library that helps with managing the version number of Git-hosted PHP projects
sensio/distribution-bundle v5.0.24 Base bundle for Symfony Distributions
sensio/framework-extra-bundle v5.2.4 This bundle provides a way to configure your controllers with annotations
sensio/generator-bundle v3.1.7 This bundle generates code for you
sensiolabs/security-checker v5.0.3 A security checker for your composer.lock
swiftmailer/swiftmailer v5.4.12 Swiftmailer, free feature-rich PHP mailer
symfony/monolog-bundle v3.3.1 Symfony MonologBundle
symfony/phpunit-bridge v3.4.21 Symfony PHPUnit Bridge
symfony/polyfill-apcu v1.10.0 Symfony polyfill backporting apcu_* functions to lower PHP versions
symfony/polyfill-ctype v1.10.0 Symfony polyfill for ctype functions
symfony/polyfill-intl-icu v1.10.0 Symfony polyfill for intl's ICU-related data and classes
symfony/polyfill-mbstring v1.10.0 Symfony polyfill for the Mbstring extension
symfony/polyfill-php56 v1.10.0 Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions
symfony/polyfill-php70 v1.10.0 Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions
symfony/polyfill-util v1.10.0 Symfony utilities for portability of PHP codes
symfony/swiftmailer-bundle v2.6.7 Symfony SwiftmailerBundle
symfony/symfony v3.4.21 The Symfony PHP framework
theseer/tokenizer 1.1.0 A small library for converting tokenized PHP source code into XML and potentially other fo...
twig/twig v2.6.2 Twig, the flexible, fast, and secure template language for PHP
webmozart/assert 1.4.0 Assertions to validate method input/output with nice error messages.
Edit:
I have read #1745 which give me the solution.
It seems that I am not the only one facing this issue. Maybe a bit more of information on the documentation could help other not loosing 3h. Something like : be carefull when mocking method with a default argument. You must add them in the map in order to work.
I have add at the end the solution.
Initial question:
I am trying to use
returnValueMap
starting with the doc example, I only change the class I am mocking fromstdClass
toSymfony\Component\DependencyInjection\ContainerInterface
and it stop working, the call to the method now allways return null instead of content of the map.Here the minimal code showing this error.
You can comment/uncomment the two line calling
getMockBuilder
to see that the responsible isContainerInterface
.Here the beginning the mapped interface
The code working
The issue was : the
get
need 2 arguments and the second one is facultative, so easily forgotten. It is required to put it on the map. It was working withstdClass
because php had no idea this method required 2 arguments. Using the interface it know and map the first two element of the map has method argument, thus nothing is left to be return.Return of command
composer info | sort