Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ebizo's avatar
Level 1

App singleton and no session

I have in my register provider singleton:

$this->app->singleton(MyCustomStateClass::class);

This class contains some logic about logged user and normally it's works, but when i run feature tests it's fails because in constructor of MyCustomStateClass i don't have access to logged user yet - Auth::user() is null. I pass to constructor Request and I check session $request->session() i get error: RuntimeException: Session store not set on request.

MyCustomStateClass is used mainly in Middlewares, and i call it by resolve() method.

Workaround for now is: if (!$this->app->runningUnitTests()) { $this->app->singleton(MyCustomStateClass::class); } and generally it works but i don't like to leave such conditions in my code. Any sugestions?

0 likes
5 replies
bearcodi's avatar

Hi,

It could be one of two things, either your not actingAs() a user in your feature test prior to making your http request, for example:

    /** @test */
    
    public function it_checks_if_a_user_needs_to_be_onboarded()
    {
        ...

        $this->actingAs(
            factory(User::class)->create()
        );

        $response = $this->get('/user');

        ...
    }

Or, you could be injecting the wrong class into your MyCustomStateClass. If you using dependency injection make sure your resolving Illuminate\Auth\AuthManager and not Illuminate\Support\Facades\Auth, as the Auth facade actually resolves the AuthManager .

I've whipped up a working example with feature and unit tests for you to take a look at.

https://github.com/bearcodi/laravel-injecting-middleware-testing-example

Hope it helps

Cheers

ebizo's avatar
Level 1

I forgot about one important things. My class is run multiple time and debug shows that Auth::user() is empty only when my class is resolved as the first time, next \Auth::user() return User model normally. So this is why tests without singleton working.

I tried your first idea but nothing changed - web is ok, testing null.

I think i have app/env specific problem (maybe third parties libs) and i need make own investigation. My guess is that session problem because i tried to pass simply session variable withSession(['foo' => 'bar']) and still no session initiated. I think MyCustomStateClass is called by UnitTest before session is initiated at all. I need to know why and where.

Ps. Laravel 5.7 here.

ebizo's avatar
Level 1

I use Feature test.

Here is my full code:

namespace Tests\Feature\Assets;

use App\Models\User;
use Tests\TestCase;
class AssetsControllerTest extends TestCase
{
    /** @test */
    public function try_to_open_without_assets()
    {
        $user = factory(User::class)->create();

        $response = $this->actingAs($user)->get(route('system.home'));

        $response->assertRedirect(route('system.assets.index'));
    }
}

I tried to move auth logic to setUp method:

    public function setUp()
    {
        parent::setUp();
        $user = factory(User::class)->create();
        $this->be($user);
    }

also doesn't work.

If i put dd($this->isAuthenticated()); in test method it return true so again - i think my singleton class is called by sth else earlier.

ebizo's avatar
Level 1

Ok, i found reason, i mean place/library what called my custom class. I put throw exception to get "frames":

 C:\laragon\www\my-app\app\Session\MyCustomStateClass.php:58
 C:\laragon\www\my-app\app\Session\MyCustomStateClass.php:42
 C:\laragon\www\my-app\vendor\laravel\framework\src\Illuminate\Container\Container.php:812
 C:\laragon\www\my-app\vendor\laravel\framework\src\Illuminate\Container\Container.php:261
 C:\laragon\www\my-app\vendor\laravel\framework\src\Illuminate\Container\Container.php:776
 C:\laragon\www\my-app\vendor\laravel\framework\src\Illuminate\Container\Container.php:658
 C:\laragon\www\my-app\vendor\laravel\framework\src\Illuminate\Container\Container.php:609
 C:\laragon\www\my-app\vendor\laravel\framework\src\Illuminate\Foundation\Application.php:759
 C:\laragon\www\my-app\vendor\laravel\framework\src\Illuminate\Foundation\helpers.php:121
 C:\laragon\www\my-app\routes\breadcrumbs.php:3
 C:\laragon\www\my-app\vendor\davejamesmiller\laravel-breadcrumbs\src\BreadcrumbsServiceProvider.php:92
 C:\laragon\www\my-app\vendor\davejamesmiller\laravel-breadcrumbs\src\BreadcrumbsServiceProvider.php:61
 C:\laragon\www\my-app\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php:29
 C:\laragon\www\my-app\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php:87
 C:\laragon\www\my-app\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php:31
 C:\laragon\www\my-app\vendor\laravel\framework\src\Illuminate\Container\Container.php:572
 C:\laragon\www\my-app\vendor\laravel\framework\src\Illuminate\Foundation\Application.php:819
 C:\laragon\www\my-app\vendor\laravel\framework\src\Illuminate\Foundation\Application.php:622
 C:\laragon\www\my-app\vendor\laravel\framework\src\Illuminate\Foundation\Application.php:733
 C:\laragon\www\my-app\vendor\laravel\framework\src\Illuminate\Foundation\Application.php:713
 C:\laragon\www\my-app\vendor\laravel\framework\src\Illuminate\Foundation\Application.php:689
 C:\laragon\www\my-app\vendor\laravel\framework\src\Illuminate\Foundation\Console\Kernel.php:300
 C:\laragon\www\my-app\tests\CreatesApplication.php:18
 C:\laragon\www\my-app\vendor\laravel\framework\src\Illuminate\Foundation\Testing\TestCase.php:91
 C:\laragon\www\my-app\vendor\laravel\framework\src\Illuminate\Foundation\Testing\TestCase.php:68

In the beginning of breadcrumbs.php i have $activeAccess = app('App\Session\MyCustomStateClass'); because in breadcrumbs also i need this specific session info. Interesting..

Please or to participate in this conversation.