What's a good way to test a user factory that depends on an external API call

82 views Asked by At

I've got a pretty straight forward user factory, except it is depending on an external API call. Since the external call has be authenticated with particular user details I'm not sure if I somehow have to mock the response or the request?

My question is if there are any suggestions on what a good way would be to user test this factory?

Thanks!

public static function getUser($id)
{
    if (!IntegerValidator::valid($id)) {
        throw new ValidationException('Invalid id provided');
    }

    $path = "/users/{$id}";
    $cache = MemcachedManager::get($path);

    if ($cache) {
        return $cache;
    }

    $client = ClientFactory::getClient();
    $result = $client->get($path);

    $user = static::createUserFromResult($result);

    MemcachedManager::set($path, $result);

    return $user;
}
2

There are 2 answers

0
shaunl On

To make this testable you need to refactor your code. You can mock dependencies in PHPUnit very easily and create a mock response for their public API method calls. For what you want to achieve, you will need to inject ClientFactory into the method and then you can use a mock object in it's place for the unit test.

0
Aleksander Wons On

You need DI to achieve this.

class Something
{
    private $client;

    public function __construct(Client $client)
    {
        $this->client = $client;
    }

    public function getUser($id)
    {
        //...
        $result = $this->client->get($path);
    }
}

class MyTest extends \PHPUnit_Framework_TestCase
{
    public function testSomething()
    {
        $someResult = ''; // Here goes your result

        $clientMock = $this->getMockBuilder(Client::class)->disableOriginalConstruction->getMock();
        $clientMock->method('get')->willReturn($someResult);

        $something = new Something($clientMock);
        $something->getUser(1);
    }
}

And avoid static methods as much as you can. It is usually better to inject dependencies than to use static methods, because you cannot mock them.