laravel / framework

The Laravel Framework.
https://laravel.com
MIT License
31.85k stars 10.79k forks source link

Exceptions::fake() not working after upgrading from Laravel v8 to v11 #52010

Closed antonkomarev closed 5 days ago

antonkomarev commented 1 week ago

Laravel Version

11.11.1

PHP Version

8.2.18

Database Driver & Version

No response

Description

I'm trying to use new feature Exceptions::fake(), but it just ignored. Not in HTTP tests, but in integration ones.

I've double checked that Concerns\InteractsWithExceptionHandling trait is exists in base test case class.

After upgrade I haven't migrated app to the new slim structure as it stated in upgrade guide:

However, we do not recommend that Laravel 10 applications upgrading to Laravel 11 attempt to migrate their application structure, as Laravel 11 has been carefully tuned to also support the Laravel 10 application structure.

Steps To Reproduce

This test is working well:

public function testWorking(): void
{
    $this->expectException(\DomainException::class);
    $this->expectExceptionMessage(
        "The order was invalid.",
    );

    app(OrderService::class)->process(
        123,
    );
}

This test is failing because it's not handling exceptions:

public function testNotWorking(): void
{
    Exceptions::fake();

    app(OrderService::class)->process(
        123,
    );

    Exceptions::assertReported(function (\DomainException $e) {
        return $e->getMessage() === 'The order was invalid.';
    });
}

This one is not working too:

public function testNotWorkingToo(): void
{
    $exceptions = Exceptions::fake();

    app(OrderService::class)->process(
        123,
    );

    $exceptions->assertReported(function (\DomainException $e) {
        return $e->getMessage() === 'The order was invalid.';
    });
}
driesvints commented 1 week ago

Heya, thanks for reporting.

We'll need more info and/or code to debug this further. Can you please create a repository with the command below, commit the code that reproduces the issue as one separate commit on the main/master branch and share the repository here? Please make sure that you have the latest version of the Laravel installer in order to run this command. Please also make sure you have both Git & the GitHub CLI tool properly set up.

laravel new bug-report --github="--public"

Please do not amend and create a separate commit with your custom changes. After you've posted the repository, we'll try to reproduce the issue.

Thanks!

antonkomarev commented 1 week ago

I'm not sure it will reproduce on v11 from scratch, I need to create v10 or below and upgrade it first

driesvints commented 1 week ago

We’ll need to figure out what’s missing from the upgrade guide if this isn’t working for you. Please indeed provide a repo and commit the upgrade steps separately

donnysim commented 5 days ago

I don't think it works in the way you expect. If you don't call a route it does not go through the exception handling pipeline and you have to specify on the test what exception you're expecting because it's not a framework exception but a direct call to a service/class etc.. The exception you see in the console is handled by the try/catch in the PHPUnit side and the exception/error does not reach the application exception handler.

donnysim commented 5 days ago

In short, you cannot do this:

    public function testNotWorkingToo(): void
    {
        Exceptions::fake();

        throw new \DomainException('The order was invalid.');

        Exceptions::assertReported(function (\DomainException $e) {
            return $e->getMessage() === 'The order was invalid.';
        });
    }

and expect that the exception magically gets silenced/swallowed.

crynobone commented 5 days ago

Thanks @donnysim