andersfloor's avatar

Dusk test does not see database update

I'm trying to replicate the Email verification lesson in Laravel 5.5 using Dusk for testing. I'm running into an issue where my test procedure does not see the database update after a user has confirmed his registration through the link.

This is my test procedure:

    public function test_a_user_may_register_but_must_confirm_email_address()
    {
        $this->browse(function (Browser $browser) {
            $browser->visit('/register')
                ->type('name', 'JohnDoe')
                ->type('email', '[email protected]')
                ->type('password', 'password')
                ->type('password_confirmation', 'password')
                ->press('Register')
                ->assertPathIs('/check_inbox')
                ->assertSee('Please check your inbox to confirm your registration');
        });

        $this->assertDatabaseHas('users', ['name' =>'JohnDoe', 'verified' => false]);

        $user = User::whereName('JohnDoe')->first();

        $this->browse(function (Browser $browser) use ($user) {
            $browser->visit("register/confirm/{$user->email_token}")
             ->assertSee("Email verified!");
        });

        // This is the line that's failing
        $this->assertDatabaseHas('users', ['name' =>'JohnDoe', 'verified' => true]);
    }

Here is the controller:

    public function checkConfirmation($email_token)
    {
        $user = User::whereEmailToken($email_token)->firstOrFail();
        $user->verified = true;
        $user->email_token = null;
        $user->save();
        // note I'm adding the verified-attribute here
        dd("Email verified! " . $user->verified);

    }

This is the artisan dusk output:

There was 1 failure:                                                                                                           
                                                                                                                               
1) Tests\Browser\ExampleTest::test_a_user_may_register_but_must_confirm_email_address                                          
Failed asserting that a row in the table [users] matches the attributes {                                                      
    "name": "JohnDoe",                                                                                                         
    "verified": true                                                                                                           
}.                                                                                                                             
                                                                                                                               
Found: [                                                                                                                       
    {                                                                                                                          
        "id": 1,                                                                                                               
        "name": "JohnDoe",                                                                                                     
        "email": "[email protected]",                                                                                        
        "password": "$2y$10$dMIS2MqW1MKNGc3lGKORROirp73q\/X.gyLv.bCzblxl3Wfq2spj6y",                                           
        "remember_token": null,                                                                                                
        "verified": 0,                                                                                                         
        "email_token": "S0vapdxiyL0nuEqiuT8rup24jlXHjL9B",                                                                     
        "google2fa_secret": null,                                                                                              
        "created_at": "2017-09-28 07:56:30",                                                                                   
        "updated_at": "2017-09-28 07:56:30"                                                                                    
    }                                                                                                                          
].                                                                                                                             
                                                                                                                               
/home/vagrant/Code/moonventory/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/InteractsWithDatabase.php:22
/home/vagrant/Code/moonventory/tests/Browser/ExampleTest.php:63                                                                

So after completing the verification link the test finds that the user is not verified in the database. However, according to my database the user has been verified successfully and artisan tinker shows that as well..

If I change the line assertSee("Email verified!") to assertSee("foo") the screenschot shows that the user was verified:

screenshot

I cannot chain the assertDatabaseHas to the $this->browse(...) because that returns a null.

If I take out the last assertDatabaseHas and put it in a separate function, the test succeeds:

        $this->browse(function (Browser $browser) use ($user) {
            $browser->visit("register/confirm/{$user->email_token}")
             ->assertSee("Email verified!");
        });

    }

    public function test_databasecheck_in_a_seperate_function()
    {
        $this->assertDatabaseHas('users', ['name' =>'JohnDoe', 'verified' => true]);
    }

... but I'd like to keep the database assertion in the same function as the other tests, since they belong together. Is that a bad idea? Am I doing something wrong or is dusk a bit wonky?

0 likes
4 replies
TesterP's avatar

Could it be a timing issue? That the database is checked before the result of the verification has been stored there? In the artisan dusk output you see that the user has been stored, but not yet verified.

Try adding a small delay before you check the db and see if that makes a difference.

$browser->pause(200);

I have noticed that sometimes Dusk is running so fast that it feels like it is ahead of itself.

P.

1 like
smnhunt's avatar

I'm having this problem too. The pause does the trick, but I can't help wondering if there is a better way?

The reason I say this is because I've just transferred a test suite from a fast Linux machine to a 2012 iMac and had to edit all of my tests to account for the fact that it is slower. My Linux box was cruising with delays of 25 ms but the iMac needs closer to 100 ms.

Maybe I should be waiting for an element (eg. an alert that tells the user that their request has been successful) rather than just a set amount of time.

thejacer87's avatar

i've added the pause, but it still doesn't work. Has anyone come up with a more elegant solution?

timur_z80's avatar

Thats because you use DatabaseTransactions trait with dusk

Please or to participate in this conversation.