Magento – Magento 2 Unit test for exception

exceptionmagento2.2phpunittestingunit tests

Got a basic question about handling Exceptions in Magento 2. I'm currently on Magento 2.2 with PHPUnit 6.2.4. I would like to write a test for a CouldNotSaveException.

Got the following code example

try {
    $this->customerDataResource->save($customerDataObject);
} catch (\Exception $e) {
    throw new CouldNotSaveException(new Phrase(
        'Unable to save customer with ID '. $customerData->getCustomerId()
    ));
}

Currently got the following usage from PHPUnit documentation

https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.exceptions.examples.ExceptionTest.php

/**
* Test save() method when exception is thrown
*/
public function testSaveException()
{
    $this->expectException(CouldNotSaveException::class);
}

I'm mocking my objects using the createMock() method. Don't really know how to write the rest of the code.

If someone could help me out that would be great.
Thanks in advance!

Best Answer

For an example your code looks like this:

class CustomerService
{
    /**
     * @var CustomerDataResource
     */
    private $customerDataResource;

    public function __construct(CustomerDataResource $customerDataResource)
    {
        $this->customerDataResource = $customerDataResource;
    }

    public function save(DataObject $customerDataObject)
    {
        try {
            $this->customerDataResource->save($customerDataObject);
        } catch (\Exception $e) {
            throw new CouldNotSaveException(new Phrase(
                'Unable to save customer with ID '. $customerDataObject->getCustomerId()
            ));
        }
    }
}

And your test method might look something like this:

/**
 * @expectedException CouldNotSaveException
 * @expectedExceptionMessage Unable to save customer with ID 1
 */
public function testSave()
{
    $customerDTO = new DataObject();
    $customerDTO->setCustomerId(1);

    // create service mock, which will throw an exception
    $customerDataResource = $this->getMockBuilder(CustomerDataResource::class)
        ->disableOriginalConstructor()
        ->getMock();
    $customerService = new CustomerService($customerDataResource);

    $customerDataResource->method('save')
        ->willThrowException(new CouldNotSaveException('Unable to save customer with ID ' . $customerDTO->getCustomerId()));

    $customerService->save($customerDTO);
}

As you can see, the test method is pretty simple and uses PHPUnit annotations to provide assertions for exceptions.

Related Topic