mikevaldez92's avatar

Test failing on Role assignment - failed asserting False is True

Hope everyone is having a wonderful Monday afternoon!

I wrote a test to check to see if a user was being assigned a Role upon visiting a particular create() route. When I manually test this through the browser, I'm seeing new Users I create be assigned the proper Role, but my test keeps failing.

I was wondering if I could get some pointers on writing a test that can properly check for this? Test output below:

PHPUnit 6.5.5 by Sebastian Bergmann and contributors.

F                                                                   1 / 1 (100%)

Time: 123 ms, Memory: 14.00MB

There was 1 failure:

1) Tests\Feature\MerchantTest::a_user_can_become_a_merchant
Failed asserting that false is true.

/Users/mikevaldez/Dropbox/code/pintinerary-bootstrap/tests/Feature/MerchantTest.php:36

FAILURES!
Tests: 1, Assertions: 1, Failures: 1.

Test code here:

    /** @test */
    public function a_user_can_become_a_merchant()
    {
        $user = factory(User::class)->create();

        $this->actingAs($user)
            ->get(route('merchant.create'));

        $this->assertTrue($user->isMerchant());
    }

Here's the create function on my MerchantController:

public function create()
    {
        if (! auth()->user())
        {
            return redirect(route('register'));
        }
        if (! auth()->user()->isMerchant())
        {
            auth()->user()->becomeAMerchant();
        }

        return view('merchant.create');
    }

Finally, here's the becomeAMerchant() and isMerchant() methods on my User model:

    public function becomeAMerchant()
    {
        return $this->assignRole('merchant');
    }

    public function isMerchant()
    {
        return $this->hasRole('merchant');
    }

Thanks so much for any advice! :)

0 likes
3 replies
tykus's avatar

Get a fresh instance of your $user:

$this->assertTrue($user->fresh()->isMerchant());

Really though a GET route is not appropriate where you have side-effects.

mikevaldez92's avatar

Thanks for the help Tykus!

Would applying these methods to the store() method on a POST route be better?

tykus's avatar

You are updating a user, so the a PUT request to the update action would be more appropriate. If you want to maintain CRUDDY controllers, you could make a controller specifically for working with Merchant users as a distinct resource in your app. @adamwathan did a Laracon talk which describes this approach really well.

Please or to participate in this conversation.