# Class Constants

When creating a test double for a class, Mockery does not create stubs out of any class constants 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 constants in Mockery would be possible, it does require an 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 - by using 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:

    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:

    // 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:

    class 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 static dependency:

    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:

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

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

    \Mockery::getConfiguration()->setConstantsMap([
        'Fetcher' => [
            'SUCCESS' => 'success',
            'FAILURE' => 'fail',
        ]
    ]);

    $mock = \Mockery::mock('Fetcher');
    var_dump($mock::SUCCESS); // (string) 'success'
    var_dump($mock::FAILURE); // (string) 'fail'