Blog de Gonzalo

DOBLES DE PRUEBA CON PHPUNIT

Antes de ponerse a ver que son los dobles de prueba en phpunit creo que hay que leer sobre las pruebas unitarias con phpunit y sobre las aserciones.
Hay funcionalidades que no dependen de otros componentes y se pueden hacer pruebas unitarias sobre esas funcionalidades. Pero hay otras funcionalidades que dependen de otros componentes y probar esas funcionalidades pueden llevar a casos indeseados, como envío de emails o cobros indeseados. Muchos diréis que los sistemas de cobros tienen modo de pruebas y que en un sistema de envío de email se puede cambiar los emails de bbdd o deshabilitar el envío de emails de ese servidor o de la máquina local. En phpunit estas pruebas se llaman dobles de pruebas. Los dobles de prueba con phpunit consiste en crear clases stub y mock. La clase mock contendrá las funcionalidades que queremos evitar que se ejecuten, por ejemplo el envío de emails. Y la clase stub es la clase de pruebas que contiene la clase mock:
E el siguiente ejemplo se puede ver que tenemos una clase user y que se quiere probar que se le manda un email. Esta es la clase stub.


use PHPUnit\Framework\TestCase;

class UserTest extends TestCase
{
    public function testNotificationIsSent()
    {
        $mock = $this->createMock(Mailer::class);
        $mock->method('sendMessage')->willReturn(true);

        $result = $mock->sendMessage('gonzalo@example.com', 'Hola');
        $this->assertTrue($result);
}

En el ejemplo de arriba se crea el objeto mock y el parámetro es Mailer::class que es la clase definida abajo. Con el método $mock->method('sendMessage') se le indica que método de la calse mailer llamar y con el método >$mock->willReturn(true) se indica que tiene que devoler y hay realizar los asserts correspondientes.

class Mailer
{

    /**
     * Send a message
     *
     * @param string $email The email address
     * @param string $message The message
     *
     * @return boolean True if sent, false otherwise
     */
    public function sendMessage($email, $message)
    {
        if (empty($email))        {
            throw new Exception;
        }
        
        // Use mail() or PHPMailer for example
        sleep(3);

        echo "send '$message' to '$email'";

        return true;
    }
}

Compartir en twitter