Search code examples
phpphpunitmockery

How to mock an aliased class with a method that returns an instance of itself?


I've been successfully using Mockery with PHPUnit tests lately. Yet, there is a dependency in a project I'm currently working that uses static method calls to interact with an API. I'm struggling to test one particular use case and it feels like I'll find other like this during the development roadmap.

Using this class as an example:

namespace Name\Space;
class User
{
    /**
     * @return \Name\Space\User[]
     */
    public static function list(): array
    {
        // ...
    }
    public static function create(array $attrs): User
    {
        // ...
    }
}

In case I just want to assert a method returns a primitive type, such as an array:

Mockery::mock('alias:\Name\Space\User')
    ->shouldReceive('list')
    ->andReturn([]);

It works fine, primarily because I'm not testing the array contents.

However, I have to call the create method, which returns an instance of the class itself (User). If I do something like this:

$user = new \Name\Space\User();
Mockery::mock('alias:\Name\Space\User')
    ->shouldReceive('create')
    ->andReturn($user);

The alias, obviously, won't work because the class was already loaded through the autoloader (composer's, in this case).

Does anyone have a suggestion on how to workaround this?


Solution

  • What about creating User in a closure?

    <?php
    
    $user = Mockery::mock('overload:\Name\Space\User')
        ->shouldReceive('create')
        ->andReturnUsing(function() {
                  return new \Name\Space\User();
        });