Testing an exception with PHPUnit/Symfony

Published on 2020-09-20 • Modified on 2020-09-20

In this snippet, we will see how to test if the code throws an exception. We will use the PHPUnit expectException() function with the FQCN of the exception as the first argument. Note that's is important to call this function before the exception is raised of it won't be intercepted. In the following tests, we check that a RuntimeException is raised for two specific cases. The last test is the nominal case where no exception occurs. As the same exception is used in the two first cases, it's essential to test the messages so we sure they correspond to two different functional points.


<?php

declare(strict_types=1);

namespace App\Tests\Unit\Tools;

use App\Samples\MyHttpKernelInterface;
use App\Tools\Filesystem;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

/**
 * @see Filesystem
 */
final class FilesystemTest extends TestCase
{
    /**
     * @return MockObject&MyHttpKernelInterface
     */
    private function getAdaptaterMock(): MockObject
    {
        return $this->getMockBuilder(MyHttpKernelInterface::class)->getMock();
    }

    /**
     * @see 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');
    }

    /**
     * @see 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);
    }

    /**
     * @see 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'));
    }
}

 More on Stackoverflow   Read the doc  Random snippet

  Work with me!