Tester une exception avec PHPUnit / Symfony

Publié le 20/09/2020 • Mis à jour le 20/09/2020


English language detected! 🇬🇧

  We noticed that your browser is using English. Do you want to read this post in this language?

Read the english version 🇬🇧 Close

Dans ce bout de code nous allons voir comment tester si un code lève une exception donnée. Nous allons utiliser la fonction PHPUnit expectException() avec la FQCN de l'exception à tester comme argument. Veuillez noter qu'il est important d'appeler cette fonction avant la levée de l'exception ou celle-ci ne sera pas interceptée. Dans les tests suivants, nous vérifions qu'une exception de type RuntimeException est levée pour deux cas spécifiques. Le dernier test représente le cas nominal ou aucune exception n'intervient. Comme la même exception est utilisée dans les deux cas, il est essentiel de tester les messages associés aux exceptions pour être sûr que l'on teste bien deux cas fonctionnels différents.


<?php declare(strict_types=1);

namespace App\Tests\Tools;

use App\Tools\Adapter;
use App\Tools\Filesystem;
use \PHPUnit\Framework\MockObject\MockObject;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

/**
 * @covers Filesystem
 */
class FilesystemTest extends KernelTestCase
{
    private function getAdaptaterMock(): MockObject
    {
        return $this->getMockBuilder(Adapter::class)->getMock();
    }

    /**
     * @covers Filesystem::write
     */
    public function testWriteRuntimeException1(): void
    {
        $adaptaterMock = $this->getAdaptaterMock();
        $adaptaterMock->method('exists')->willReturn(true);
        $fileSystem = new Filesystem($adaptaterMock);
        $this->expectException(\RuntimeException::class);
        $this->expectExceptionMessage('The file foo already exists and can not be overwritten');
        $fileSystem->write('foo', 'bar', false);
    }

    /**
     * @covers Filesystem::write
     */
    public function testWriteRuntimeException2(): void
    {
        $adaptaterMock = $this->getAdaptaterMock();
        $adaptaterMock->method('exists')->willReturn(true);
        $adaptaterMock->method('write')->willReturn(0);
        $fileSystem = new Filesystem($adaptaterMock);
        $this->expectException(\RuntimeException::class);
        $this->expectExceptionMessage('The content of the file foo could not be written');
        $fileSystem->write('foo', 'bar', true);
    }

    /**
     * @covers Filesystem::write
     */
    public function testWriteNominal(): void
    {
        $expected = 3; // excepted number of bytes written
        $adaptaterMock = $this->getAdaptaterMock();
        $adaptaterMock->method('exists')->willReturn(false);
        $adaptaterMock->method('write')->willReturn($expected);
        $fileSystem = new Filesystem($adaptaterMock);
        self::assertSame($expected, $fileSystem->write('foo', 'bar', false));
    }
}

 Plus sur Stackoverflow   Lire la doc  Snippet aléatoire