Posts tagged 'php'

Mockery partial mocks

published on January 28, 2018.

In dealing with legacy code I often come across some class that extends a big base abstract class, and the methods of that class call methods on that big base abstract class that do an awful lot of things. I myself have written such classes and methods in the past. Live and learn.

One of the biggest problems with this kind of code is that it is pretty hard to test. The methods from the base class can return other objects, have side effects, do HTTP calls…

A typical example of this would be a base model class that has a getDb() method:

AbstractModel.php

<?php

abstract class AbstractModel
{
    protected $db = null;

    protected function getDb()
    {
        if ($this->db == null) {
            $db = Config::get('dbname');
            $user = Config::get('dbuser');
            $pass = Config::get('dbpass');
            $this->db = new PDO('mysql:host=localhost;dbname='.$db, $user, $pass);
        }
        return $this->db;
    }
}

which can be called in child classes to get access to the database connection:

ArticleModel.php

<?php

class ArticleModel extends AbstractModel
{
    public function listArticles()
    {
        $db = $this->getDb();
        $stmt = $db->query('SELECT * FROM articles');

        return $stmt->fetchAll();
    }
}

If we want to write unit tests for this listArticles() method, the best option would probably be to refactor the models so that the database connection can be injected either through the constructor, or with a setter method.

In case refactoring is not an option for whatever reason, what we can do is to create a partial mock of the ArticleModel using Mockery and then mock (well, stub to be more precise) out only the getDb() method that will always return a mocked version of the PDO class:

tests/ArticleModelTest.php

<?php

use Mockery\Adapter\Phpunit;

class ArticleModelTest extends MockeryTestCase
{
    public function testListArticlesReturnsAnEmptyArrayWhenTheTableIsEmpty()
    {
        $stmtMock = \Mockery::mock('\PDOStatement');
        $stmtMock->shouldReceive('fetchAll')
            ->andReturn([]);
        $pdoMock = \Mockery::mock('\PDO');
        $pdoMock->shouldReceive('query')
            ->andReturn($stmtMock);

        // Create a partial mock of ArticleModel
        $articleModel = \Mockery::mock('ArticleModel')->makePartial();

        // Stub the getDb method on the ArticleModel
        $articleModel->shouldReceive('getDb')
            ->andReturn($pdoMock);

        // List all the articles
        $result = $articleModel->listArticles();
        $expected = [];

        $this->assertSame($expected, $result);
    }
}

When we tell Mockery to make a partial mock of a class, any method on that partially mocked class that has expectations set up will be mocked, but calls to other methods Mockery will pass through the real class. In other words, even though the ArticleModel is a partial mock, anytime we call the listArticles() method Mockery will pass that call to the original method, and only the calls to the getDb() method are being mocked.

Using partial mocks should probably be an option of a last resort and we should always aim to refactor code to be easier for testing, but there are cases when they can really help us in testing legacy code.

Happy hackin’!

Mockery return values based on arguments

published on December 12, 2017.

Sometimes when working with Mockery mock objects, we want to tell a mocked method to return different values for different arguments. It is a rare occasion when I need this feature, but every time I need it, I’m happy it’s there.

The feature that allows us to return different values based on arguments is the andReturnUsing Mockery method, which takes a closure as an argument:

example.php

$dependencyMock = \Mockery::mock('SomeDependency');
$dependencyMock->shouldReceive('callDependency')
    ->andReturnUsing(function ($argument) {
        if ($argument <= 10) {
            return 'low';
        }

        return 'high';
    });

$dependencyMock->callDependency(10); // 'low'
$dependencyMock->callDependency(11); // 'high'

Any number of times we call our callDependency method on our mock object with a number 10 or less, it will return 'low', otherwise it will return 'high'.

Not much of an example, so let’s take a look at one a bit closer to a real world scenario.

Say we’re using Doctrine’s entity manager to get repositories for our entities in a service class:

src/ArticleService.php

<?php

class ArticleService
{
    public function __construct(EntityManager $em)
    {
        $this->articleRepo = $em->getRepository(Entity\Article::class);
        $this->authorRepo = $em->getRepository(Entity\Author::class);
    }
}

Not the best of the codes, but we’ll manage. The entity manager receives two calls to the getRepository method, once for the Article entity, once for the Author entity.

In a test case we could then set up the mocks like so:

tests/ArticleServiceTest.php

<?php

class ArticleServiceTest extends MockeryTestCase
{
    public function setup()
    {
        $this->authorRepositoryMock = \Mockery::mock(AuthorRepository::class);
        $this->articleRepositoryMock = \Mockery::mock(ArticleRepository::class);
        $this->entityManagerMock = \Mockery::mock(EntityManager::class);
    }

    public function testArticleService()
    {
        $repositoryMap = [
            'Entity\Author' => $this->authorRepositoryMock,
            'Entity\Article' => $this->articleRepositoryMock,
        ];
        $this->entityManagerMock->shouldReceive('getRepository')
            ->andReturnUsing(function($argument) use ($repositoryMap) {
                return $repositoryMap[$argument];
            });

        $articleService = new ArticleService($this->entityManagerMock);
    }
}

In the setup method we create the three mock objects that we need and then in the test method we create a $repositoryMap to help us map entities to repositories. The repository map could have been created in the andReturnUsing closure as well.

Now when we instantiate the ArticleService with the mocked entity manager, that mocked entity manager will receive two calls to the getRepository method in the ArticleServices constructor, and it will use the closure defined in andReturnUsing to return the correct repository mock objects.

More than one way to do it

Of course there is another way to achieve the same thing and that’s by using andReturn for the return value expectations, but it’s a bit more to write:

tests/ArticleServiceTest.php

<?php
    public function testArticleService()
    {
        $this->entityManagerMock->shouldReceive('getRepository')
            ->with('Entity\Author')
            ->andReturn($this->authorRepositoryMock);
        $this->entityManagerMock->shouldReceive('getRepository')
            ->with('Entity\Article')
            ->andReturn($this->articleRepositoryMock);

        $articleService = new ArticleService($this->entityManagerMock);
    }

It does the same thing as the previous thing. We might even argue that this second example is even clearer than the first example, sure, for a relatively small argument “map”. But if we need to handle a case with more than just two possible arguments, andReturnUsing can help us in those cases.

Happy hackin’!

P.S.: The proper way to do this actually would be to refactor that ArticleService to not get the two repositories from the entity manager, but to inject them directly instead.

Reacting to promises

published on November 29, 2017.

I was working on something that includes the usage of ReactPHP promises. Given that I haven’t had the chance to take a closer look at it yet, I decided that this is the right time for it.

ReactPHP has several different components, with the end goal of providing a low-level library for event-driven programming in PHP. The one component I want to talk about today is the promise component, which is a Promises/A implementation for PHP.

What this promise library allows us is a nicer workflow with asynchronous code.

With promises, when we want to execute something asynchronously we defer the work that will be executed asynchronously. The Deferred unit of work will complete sometimes in the future, but we don’t know when. But it does promise that the work will be done, one way or the other.

The Promise is a sort of a placeholder for the result that will eventually be returned from our deferred work. This promise can then either be resolved or rejected by our deferred. When a promise is resolved successfully it has an associated value, and when it is rejected it has an associated reason for the rejection.

We use the then method on the promise to register handlers that will be called when the deferred is resolved or rejected.

To install the React/Promise component, run:

$ composer require react/promise

An example

Let’s say we have some code that does some asynchronous work. Checking the HTTP status code of a bunch of URLs, for example. We could create an invokable class that extends the Deferred:

FetchStatusCodes.php

<?php declare(strict_types=1);

use React\Promise\Deferred;

class FetchStatusCodes extends Deferred
{
    public function __invoke(array $urls)
    {
        $multiHandle = curl_multi_init();

        $handles = $this->getHandlesForUrls($urls, $multiHandle);

        $this->executeMultiHandle($multiHandle);

        $statusCodes = $this->getStatusCodes($handles);

        curl_multi_close($multiHandle);

        $successRate = $this->calculateSuccessRate($statusCodes);

        if ($successRate > 50) {
            $this->resolve($statusCodes);
        } else {
            $this->reject('Success rate too low: ' . $successRate);
        }
    }
}

I’ve left out here a bunch of code that deals with the actual fetching of the status codes, just to keep the “noise” down. The full example is available in this repository.

The important thing here is that we extend React\Promise\Deferred and that at the end we call the resolve() method to resolve this deferred if the success rate is over 50%, or that we call the reject() method if the success rate is below 50%.

The set up of the actual promise and its handlers would look something like this:

promise.php

<?php

$statusCodes = new FetchStatusCodes();
$promise = $statusCodes->promise();

$promise
    ->then(
        function($value) {
            var_dump($value);
        },
        function($reason) {
            echo $reason . PHP_EOL;
        }
    );

$urls = [
    'https://example.com/',
    'https://stackoverflow.com/',
    'https://www.google.com/',
    'https://www.google.com/no-such-url',
    'https://www.google.com:81'
];
$statusCodes($urls);

We create the FetchStatusCodes deferred object and get the promise. We setup the resolve and reject handler callbacks in the then method. They don’t do much for now:

  • the resolve handler dumps the value it got,
  • the reject handler prints out the reason of the rejection.

The output for a resolved promise would be something like this:

$ php promise.php
/home/robert/projects/react-promise-example/promise.php:32:
array(5) {
  'https://example.com/' => int(200)
  'https://stackoverflow.com/' => int(200)
  'https://www.google.rs/' => int(200)
  'https://www.google.com/no-such-url' => int(404)
  'https://www.google.com:81/' => int(0)
}

We’re not done yet!

The example above where we call the then method to set up our resolve/reject handlers, isn’t quite correct. Why?

When we call the then method it actually returns a new Promise. This feature of the Promises/A specification allows us to chain promises together.

On this second promise we can again set up our resolve/reject handlers calling the then method on it, same as we do for our first promise. The resolve handler of the second promise will be called with the return value of either the resolve or the reject handler of the first promise. The reject handler of the second promise will be called when either the resolve or the reject handler of the first promise throws an exception. And the then method of our second promise again returns a new, third promise.

Let’s see if an example makes it a bit more clearer:

promise.php

<?php

$statusCodes = new FetchStatusCodes();
$firstPromise = $statusCodes->promise();

$secondPromise = $firstPromise->then(
    function($statusCodes) {
        $successCodes = array_filter($statusCodes, function ($code) {
            if ($code >= 200 && $code < 300) {
                return true;
            }
            return false;
        });
        return $successCodes;
    },
    function($reason) {
        // handle rejected promise
        // gets called when Deferred gets reject-ed
    }
);

$thirdPromise = $secondPromise->then(
    function ($successCodes) {
        return json_encode($successCodes);
    },
    function ($reason) {
        // handle rejected promise
        // gets called when $firstPromise handlers throw an exception
    }
);

$urls = [
    'https://example.com/',
    'https://stackoverflow.com/',
    'https://www.google.com/',
    'https://www.google.com/no-such-url',
    'https://www.google.com:81'
];
$statusCodes($urls);

When our FetchStatusCodes deferred resolves, it will call the resolve handler of the $firstPromise. In that first resolve handler we get only the successful status codes and return them.

With this return from the resolve handler of the first promise, we “trigger” the resolve handler of the $secondPromise where we can, for example, json_encode our success codes. By returning this JSON string from the resolve handler of the second promise, we again “trigger” the resolve handler of the $thirdPromise, and so on.

Almost done!

When we call then, we make a new promise.

To actually be done with all the promises, we need to call the done method on the last promise in our chain. With done we stop making promises and use the result of our last promise:

promise.php

<?php
$thirdPromise->done(
    function ($jsonString) {
        echo $jsonString . PHP_EOL;
    },
    function ($reason) {
        // handle rejected promise
        // gets called when $secondPromise handlers throw an exception
    }
);

If we’d run the example now, we’d get something like this:

$ php promise.php | json_pp
{
   "https://example.com/" : 200,
   "https://www.google.rs/" : 200,
   "https://stackoverflow.com/" : 200
}

We additionally pipe the output of our example script to json_pp to pretty print the JSON string.

Now we’re done

ReactPHP promises have an ExtendedPromisesInterface that include additional shortcut and utility methods that are not part of the Promise/A specification. Their docs include some more examples, and Cees-Jan Kiewiet looks at examples using the react/dns component, among other things.

When we deal with asynchronous code in PHP, using ReactPHP promises gives us a way to deal with it in a much nicer, saner way.

Happy hackin’!

PHP FPM slow log

published on November 23, 2017.

The other day I was going through the configuration file for php-fpm, when I noticed a configuration directive I haven’t before: slowlog. I guess it’s been around for a while, I just never noticed it.

The php-fpm slow log is a pool configuration, meaning that we configure it in www.conf, and has two directives for it:

  • the slowlog, which is a path to a file where the slow requests will be logged,
  • and request_slowlog_timeout is a time unit after which PHP will dump a backtrace for that request in to the slow log file. We can configure it to be in seconds, minutes, hours, or days.

What’s in the box backtrace?

It has the date and time for when the slow request happened, the pool and PID for the php-fpm process. script_filename is the entry point to the request, and the backtrace includes a list of function calls up until the moment when the request_slowlog_timeout was hit.

[23-Nov-2017 15:28:21]  [pool www] pid 8992
script_filename = /var/www/example/web/app_dev.php
[0x00007efe32a14a40] sleep() /var/www/example/src/AppBundle/Controller/DefaultController.php:18
[0x00007efe32a149d0] indexAction() /var/www/example/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php:153
[0x00007efe32a14960] call_user_func_array() /var/www/example/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php:153
[0x00007efe32a14470] handleRaw() /var/www/example/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php:68
[0x00007efe32a14320] handle() /var/www/example/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php:169
[0x00007efe32a14250] handle() /var/www/example/web/app_dev.php:29

Even though it doesn’t reveal too much, together with other profiling tools, like Xdebug and kcachegrind, it can help us a great deal on finding and fixing performance problems in web applications.

Happy hackin’!

What implements an interface

published on November 02, 2017.

Creating and implementing interfaces in our code is important. It helps with swapping out components, eases testing, separates the what from the how.

But, it’s not enough just to slap an interface on a class and be done with it.

We also need to consider on what are we putting that interface on.

An example

Say, we’re creating a queuing system for an RSS feed reader. We can tell the queue to queue the feed URLs. Depending on our needs, we can use something like RabbitMq, or a database, to use as a queuing mechanism.

We haven’t decided on that yet, but either way, we start with an interface for this imaginary queue:

<?php declare(strict_types=1);

namespace Example\Infrastructure\Queue;

use Example\Domain\Rss\FeedUrl;

interface FeedUrlQueue
{
    public function add(FeedUrl $feedUrl);
}

By having this nice little interface, we can TDD the part of the code that will use an implementation of this interface.

After a while we decide we’ll go with a database queuing mechanism first, so we create an implementation for the FeedUrlQueue interface:

<?php declare(strict_types=1);

namespace Example\Infrastructure\Storage\Database;

use Example\Domain\Rss\FeedUrl;

class FeedUrlTable extends AbstractTable implements FeedUrlQueue
{
    public function add(FeedUrl $feedUrl)
    {
        $qb = $this->getQueryBuilder();

        $query = $qb->insert('feed_urls')
            ->values(
                [
                    'url' => '?',
                ]
            )
            ->setParameter(0, (string) $feedUrl);

        $query->execute();
    }
}

That’s nice! We have an interface, a concrete implementation, and the possibility to write new implementations and swap them out with existing ones with little effort.

Job well done.

Is it done, let alone well?

Sure it is, I repeat, we have an interface, a concrete implementation, and the possibility to write new implementations and swap them out with existing ones with little effort.

Something’s fishy

There’s three things that stand out for me here, telling me that something is not quite right with this code.

First, a class that represents a Table, also is a FeedUrlQueue. It really shouldn’t be two things at the same time. It either should be a queue, or a table, most certainly not both.

Second, a class whose only responsibility should be to store an URL into a database, no matter from where that URL comes from, is now limited to store feed URLs that come from the queue. OK, this may, or may not be, a legitimate limitation we decided on.

And third, it is also responsible to figure out how can it transform a FeedUrl domain object into a string that can be stored in the database. Does it have a __toString magic method, so we can cast it to a string? Or maybe it’s legacy code so it has one of those toString() method which we need to call? We don’t know without looking.

Killing three giants with one stone

A better, a correct way, would be to have something like a DatabaseFeedUrlQueue that implements the FeedUrlQueue, and uses the FeedUrlTable:

<?php declare(strict_types=1);

namespace Example\Infrastructure\Queue;

use Example\Domain\Rss\FeedUrl;

class DatabaseFeedUrlQueue implements FeedUrlQueue
{
    protected $table;

    public function __construct(FeedUrlTable $table)
    {
        $this->table = $table;
    }

    public function add(FeedUrl $feedUrl)
    {
        $payload = [
            'url' => (string) $feedUrl
        ];
        $this->table->save($payload);
    }
}

and the FeedUrlTable becomes something like this:

<?php declare(strict_types=1);

namespace Example\Infrastructure\Storage\Database;

class FeedUrlTable extends AbstractTable
{
    public function save(array $payload)
    {
        $qb = $this->getQueryBuilder();

        $query = $qb->insert('feed_urls')
            ->values(
                [
                    'url' => '?',
                ]
            )
            ->setParameter(0, $payload['url']);

        $query->execute();
    }
}

By refactoring the code like this, we pretty much fix all three problems at once:

  • a DatabaseFeedUrlQueue is a FeedUrlQueue, and the FeedUrlTable can stop being two things at once;
  • there’s a clearer separation of concerns, the DatabaseFeedUrlQueue is responsible to create the payload, and FeedUrlTable is responsible to store it;
  • the storage layer knows nothing about our domain objects and how to use them.

Yes, now we have one more class to maintain, but the overall maintainability, I believe, is reduced, as it is much clearer what each class does.

Happy hackin’!

Robert Basic

Robert Basic

Software engineer, consultant, open source contributor.

Let's work together!

If you require outsourcing or consulting help on your projects, I'm available!

Robert Basic © 2008 — 2019
Get the feed