Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
antonkomarev opened this issue Jul 3, 2024 · 7 comments
Closed

Comments

@antonkomarev
Copy link
Contributor

antonkomarev commented Jul 3, 2024

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.';
    });
}
@antonkomarev antonkomarev changed the title Exceptions::fake() not working after upgrading from v8 to v11 Exceptions::fake() not working after upgrading from Laravel v8 to v11 Jul 3, 2024
@driesvints
Copy link
Member

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
Copy link
Contributor Author

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

@driesvints
Copy link
Member

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
Copy link
Contributor

donnysim commented Jul 11, 2024

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
Copy link
Contributor

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
Copy link
Member

Thanks @donnysim

@nickezekias
Copy link

nickezekias commented Dec 7, 2024

Hello guys!
I'm using latest laravel 11 as fo date of writing, and I still get the same Exceptions::fake() problem in unit tests.

Here is my test code

<?php

namespace Tests\Unit;

use App\Exceptions\UnknownRoleException;
use App\Models\User;
use Illuminate\Support\Facades\Exceptions;
use PHPUnit\Framework\TestCase;

class UserTest extends TestCase
{
    /**
     * A basic unit test example.
     */
    public function test_set_roles_for_only_known_roles(): void
    {
        
        $user = new User;
        
        Exceptions::fake();
        $user->setRoles(['guest']);

        Exceptions::assertReported(UnknownRoleException::class);
    }
}

This is the error I get when the test fails:
Illuminate\Support\Testing\Fakes\ExceptionHandlerFake::__construct(): Argument #1 ($handler) must be of type Illuminate\Contracts\Debug\ExceptionHandler, null given, called in /var/www/html/vendor/laravel/framework/src/Illuminate/Support/Facades/Exceptions.php on line 54

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants