Summer Sale! All accounts are 50% off this week.

chrisrebacz's avatar

Acting As User without Authenticable Trait

Hello all--

Let me begin by saying I am very very new to unit testing. I am using the Cartalyst Sentinel package for authentication/authorization, and I would like to test that certain routes are properly redirected based on a particular user role.

My challenge is that Sentinel does not extend the Authenticatable trait, which means I cannot use the unit test helper actingAs(). This is the error I received.

ErrorException: Argument 1 passed to Illuminate\Foundation\Testing\TestCase::actingAs() must be an instance of Illuminate\Contracts\Auth\Authenticatable, instance of Cartalyst\Sentinel\Users\EloquentUser given

SInce the Laravel testing helper won't work for me, I'm hoping that there is a general phpunit way to do this. Unfortunately, I cannot find anything in my google searches. Can someone help point me in the right direction here?

Appreciate any guidance you all can provide!

0 likes
6 replies
webkenny's avatar

Don't hate me for saying this but I think you're probably looking for Behat (functional testing), not unit testing. Unit testing should stand on its own with as little outside involvement as possible. i.e. I pass you something and I get something I expect back. With functional testing of the Behat ilk you can do this kind of thing:

Given I am logged in
And I have Foo role
When I visit /some/path
Then I am redirected to /some/redirect/destination

Those statements are mapped to annotations in a PHP class.

    /**
     * @When /^I visit$/
     */
    public function iVisit($path)
    {
    //Do something to test
    }

Laracasts has a great series on Behat. If you have the time, I strongly suggest checking it out. There's also at least 20 tutorials on it out there that you can just lift some code from to try it out.

Sorry it's not the PHPUnit answer you were looking for but this is really more the game of Functional and not Unit tests. Hope this helps a bit.

chrisrebacz's avatar

Thanks for the quick response. I'll take a look at the Behat series again. I tried to go through it before and could never get it set up correctly. Hopefully, it will make more sense now that I have a bit more experience with Laravel.

A follow-up question if you don't mind, so that I better understand the distinction. Theoretically, the distinction between unit tests and functional testing makes sense. However, when I start to look at the examples that people use for unit tests, this distinction starts to blur in my mind.

For example, in the Laravel 5.1 documentation on testing, we see the following:


 public function testApplication()
    {
        $user = factory('App\User')->create();

        $this->actingAs($user)
             ->withSession(['foo' => 'bar'])
             ->visit('/')
             ->see('Hello, '.$user->name);
    }

When I look at all of the methods within TestCase (such as assertRedirectedToRoute), this seemed to be exactly what I wanted to test. If I was using the default Auth package, I wouldn't have had an issue, and wouldn't have even thought about the distinction. What is the difference between using this PHPUnit example and the Behat one you mentioned?

webkenny's avatar

Don't mind at all. Happy to discuss it. :) It's a fair point and there's no hard and fast rule. In fact, looking at the example you're providing and reading over that page I can see how this is even confusing my understanding of things. My honest guess is that Laravel attempts to give you everything you need to build a full stack application. With that in mind, it appears this is a bit of a diversion from the normal Unit testing that in theory we are used to.

I'm going to park my response on this and hope someone else floats by and sees our chat. I'd like some more clarity on this too. I'm not new to testing or PHP but I am to Laravel (used to be a Drupal/Symfony2 guy). When I look at this, it's what I would expect a library like Mink to do.

I have to write a few tests today as well and if i find anything in my travels, I'll circle back.

chrisrebacz's avatar

Thank you. I appreciate your time and insight on this.

Your comments made me think about Jeffery's Integrated package that was included in 5.1. There seems to be a blurring between the different 'types' of testing here--which doesn't necessarily mean it is a bad thing. The simplicity as seen in the Laravel documentation and in the Intuitive Integrated Testing series is the catalyst that led me to try testing in the first place.

It is just difficult because those testing options seem to be tied to the Auth package, which I'm unfortunately not able to use.

jferdi24's avatar

Hello,

You can add first() when you create user

$user = factory('App\User')->create()->first();
3 likes

Please or to participate in this conversation.