PHPunit Assert That an Exception Was Thrown

PHPUnit assert that an exception was thrown?


<?php
require_once 'PHPUnit/Framework.php';

class ExceptionTest extends PHPUnit_Framework_TestCase
{
public function testException()
{
$this->expectException(InvalidArgumentException::class);
// or for PHPUnit < 5.2
// $this->setExpectedException(InvalidArgumentException::class);

//...and then add your test code that generates the exception
exampleMethod($anInvalidArgument);
}
}

expectException() PHPUnit documentation

PHPUnit author article provides detailed explanation on testing exceptions best practices.

PHPUnit - testing for exception not thrown?

If an uncaught or unexpected exception is thrown, the test will fail. You don't have to do anything special, just run the code being tested. If there are no other assertions in the test method, you'll also have to do $this->expectNotToPerformAssertions(); or you'll get a warning that the test doesn't perform any assertions.

public function testCannotBeCreatedFromInvalidEmailAddress(): void
{
$this->expectNotToPerformAssertions();
Email::fromString('invalid'); // If this throws an exception, the test will fail.
}

How to assert Errors instead of Exception in phpunit?

Found the solution. Using error_reporting(2); in a TestCase's setUp method ensure phpunit can convert all Errors in Exceptions. I tried various error reporting levels, but only the one above works (see the error reporting levels). In this case was simple to me:

class DivisionTest extends TestCase
{
public function setUp() : void
{
$this->division = new Division;
error_reporting(2);
}

/**
* When divide by zero (x / 0) should throw an Error.
* @expectedException DivisionByZeroError
*/
public function testDivedByZeroThrowException()
{
// Act
$result = $this->division->run(0, 5); // 5 : 0
}
}

Now this test returns Success!!! For more information visit Testing PHP Errors.

Symfony/PhpUnit - How to test that an Exception is throws or not in a Service

SOLVED:

The problem was with my $contraintViolationMock which always returned empty data.
I have to retrieve violations before and test that it's match with the mock violations. I think, it's the more simple solution instead of creating manually a ConstraintViolationList.
If you have a better solution, i'll take it.

    public function testValidatorForUser()
{
$user = new User();
$user->setEmail('test');
$validator = self::$container->get(ValidatorInterface::class);
$violations = $validator->validate($user);

$validatorMock = $this->createMock(ValidatorInterface::class);

$validatorMock->expects($this->once())
->method('validate')
->willReturn($violations);

$this->expectException(InvalidDataException::class);

$validatorService = new ValidatorService($validatorMock);
$validatorService->validate($user);
}

Can't make assertions because exceptions are crashing my test in Laravel

I was having a problem with the ValidationException crashing my test because I disabled exception handling. I disabled exception handling so I can debug my tests better (ironic, I know) and I forgot that I did this.

class ... extends TestCase 
{
protected function setUp()
{
/**
* This disables the exception handling to display the stacktrace on the console
* the same way as it shown on the browser
*/
parent::setUp();
$this->withoutExceptionHandling();
}

Removing $this->withoutExceptionHandling(); now allows me to do assertions on the response.

There was 1 failure:

1) Tests\Feature\ScheduleTest::request_schedule_with_invalid_bdate
Expected status code 200 but received 422.
Failed asserting that false is true.

Relevant links:
- https://github.com/laravel/framework/issues/26013
- laravel phpunit withexceptionhandling

PHPUnit doesn't continue test after expecting an exception

Even with setExpectedException, your test is still regular PHP code, and follows PHP's normal rules. If an exception is thrown, program flow immediately jumps out of the current context until it reaches a try/catch block.

In PHPUnit, when you use setExpectedException, it tells PHPUnit's core that when it should be expecting an exception from the code that's about to run. It therefore waits for it with a try/catch block and passes the test if the catch is called with the type of exception it is expecting.

However, within your test method, the normal PHP rules still apply -- when the exception happens, that's the end of the current code block. Nothing more in that method will be executed, unless you have your own try/catch block within the test method.

So therefore, in order to test multiple exceptions, you have a few options:

  1. Add your own try/catch to the test method, so that you can carry on with further tests within that method after the first exception.

  2. Split the tests into separate methods, so that each exception is in its own test.

  3. This particular example looks like a good case to use PHPUnit's dataProvider mechanism, because you're basically testing the same functionality with two sets of data. The dataProvider feature allows you to define a separate function that contains an array of input data for each set of values you want to test. These values are then passed one set at a time into the test method. Your code would look something like this:

    /**
    * @dataProvider providerConfigOverriding
    */
    public function testConfigOverriding($filename, $expectedExceptionText) {
    $this->dependencyContainer = new DependencyContainer(__DIR__ . "/../../Resources/valid_json.json");
    $this->assertEquals('overriden', $this->dependencyContainer->getConfig('shell_commander')['pygmentize_command']);

    $this->setExpectedException('Exception', $expectedExceptionText);
    $this->dependencyContainer = new DependencyContainer($filename);
    }

    public function providerConfigOverriding() {
    return array(
    array('unexisting_file', 'Configuration file at path "unexisting_file" doesn\'t exist.'),
    array(__DIR__ . "/../../Resources/invalid_json.json", "Configuration JSON file provided is not valid."),
    );
    }

Hope that helps.



Related Topics



Leave a reply



Submit