Blame | Letzte Änderung | Log anzeigen | RSS feed
.. index::single: Cookbook; Class ConstantsClass Constants===============When creating a test double for a class, Mockery does not create stubs out ofany class constants defined in the class we are mocking. Sometimes though, thenon-existence of these class constants, setup of the test, and the applicationcode itself, it can lead to undesired behavior, and even a PHP error:``PHP Fatal error: Uncaught Error: Undefined class constant 'FOO' in ...``While supporting class constants in Mockery would be possible, it does requirean awful lot of work, for a small number of use cases.Named Mocks-----------We can, however, deal with these constants in a way supported by Mockery - byusing :ref:`creating-test-doubles-named-mocks`.A named mock is a test double that has a name of the class we want to mock, butunder it is a stubbed out class that mimics the real class with canned responses.Lets look at the following made up, but not impossible scenario:.. code-block:: phpclass Fetcher{const SUCCESS = 0;const FAILURE = 1;public static function fetch(){// Fetcher gets something for us from somewhere...return self::SUCCESS;}}class MyClass{public function doFetching(){$response = Fetcher::fetch();if ($response == Fetcher::SUCCESS) {echo "Thanks!" . PHP_EOL;} else {echo "Try again!" . PHP_EOL;}}}Our ``MyClass`` calls a ``Fetcher`` that fetches some resource from somewhere -maybe it downloads a file from a remote web service. Our ``MyClass`` prints outa response message depending on the response from the ``Fetcher::fetch()`` call.When testing ``MyClass`` we don't really want ``Fetcher`` to go and downloadrandom stuff from the internet every time we run our test suite. So we mock itout:.. code-block:: php// Using alias: because fetch is called statically!\Mockery::mock('alias:Fetcher')->shouldReceive('fetch')->andReturn(0);$myClass = new MyClass();$myClass->doFetching();If we run this, our test will error out with a nasty``PHP Fatal error: Uncaught Error: Undefined class constant 'SUCCESS' in ..``.Here's how a ``namedMock()`` can help us in a situation like this.We create a stub for the ``Fetcher`` class, stubbing out the class constants,and then use ``namedMock()`` to create a mock named ``Fetcher`` based on ourstub:.. code-block:: phpclass FetcherStub{const SUCCESS = 0;const FAILURE = 1;}\Mockery::namedMock('Fetcher', 'FetcherStub')->shouldReceive('fetch')->andReturn(0);$myClass = new MyClass();$myClass->doFetching();This works because under the hood, Mockery creates a class called ``Fetcher``that extends ``FetcherStub``.The same approach will work even if ``Fetcher::fetch()`` is not a staticdependency:.. code-block:: phpclass Fetcher{const SUCCESS = 0;const FAILURE = 1;public function fetch(){// Fetcher gets something for us from somewhere...return self::SUCCESS;}}class MyClass{public function doFetching($fetcher){$response = $fetcher->fetch();if ($response == Fetcher::SUCCESS) {echo "Thanks!" . PHP_EOL;} else {echo "Try again!" . PHP_EOL;}}}And the test will have something like this:.. code-block:: phpclass FetcherStub{const SUCCESS = 0;const FAILURE = 1;}$mock = \Mockery::mock('Fetcher', 'FetcherStub')$mock->shouldReceive('fetch')->andReturn(0);$myClass = new MyClass();$myClass->doFetching($mock);Constants Map-------------Another way of mocking class constants can be with the use of the constants map configuration.Given a class with constants:.. code-block:: phpclass Fetcher{const SUCCESS = 0;const FAILURE = 1;public function fetch(){// Fetcher gets something for us from somewhere...return self::SUCCESS;}}It can be mocked with:.. code-block:: php\Mockery::getConfiguration()->setConstantsMap(['Fetcher' => ['SUCCESS' => 'success','FAILURE' => 'fail',]]);$mock = \Mockery::mock('Fetcher');var_dump($mock::SUCCESS); // (string) 'success'var_dump($mock::FAILURE); // (string) 'fail'