This file is indexed.

/usr/share/doc/php-mockery/html/_sources/cookbook/class_constants.rst.txt is in php-mockery-doc 1.0-0ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
.. index::
    single: Cookbook; Class Constants

Class Constants
===============

When creating a test double for a class, Mockery does not create stubs out of
any class contants defined in the class we are mocking. Sometimes though, the
non-existence of these class constants, setup of the test, and the application
code 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 contants in Mockery would be possible, it does require
an awful lot of work, for a small number of use cases.

We can, however, deal with these constants in a way supported by Mockery - by
using :ref:`creating-test-doubles-named-mocks`.

A named mock is a test double that has a name of the class we want to mock, but
under 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:: php

    class 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 out
a response message depending on the response from the ``Fetcher::fetch()`` call.

When testing ``MyClass`` we don't really want ``Fetcher`` to go and download
random stuff from the internet every time we run our test suite. So we mock it
out:

.. 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 our
stub:

.. code-block:: php

    class FetcherStub
    {
        const SUCCESS = 0;
        const FAILURE = 1;
    }

    \Mockery::mock('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 static
dependency:

.. code-block:: php

    class 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:: php

    class FetcherStub
    {
        const SUCCESS = 0;
        const FAILURE = 1;
    }

    $mock = \Mockery::mock('Fetcher', 'FetcherStub')
    $mock->shouldReceive('fetch')
        ->andReturn(0);

    $myClass = new MyClass();
    $myClass->doFetching($mock);