简体   繁体   中英

Mocking Password facade in Laravel 4

I'm trying to write phpunit tests for several controller actions. Everything seems to be fine except for mocking the Password facade.

One of the actions ("forgot password") goes like this:

if (Auth::check())
    //return a redirect since the user is already logged in

switch ($response = Password::remind(Input::only('email')))
{
    case Password::INVALID_USER:
        //return a redirect with error messages

    case Password::REMINDER_SENT:
        //return a redirect with success message flushed
}

Both Auth and Password are facades and come with Laravel by default.

Testing the Auth::check() part works just fine:

Auth::shouldReceive('check')->
    once()->
    andReturn(false);  //or true depending on my test case

But when I try the same attempt for Password::remind() call it doesn't work:

Password::shouldReceive('remind')->
    once()->
    andReturn(Password::INVALID_USER);

I get "SQLSTATE Access denied" exception meaning the app is trying to access the DB.

I also tried adding with(array()) to my test or even binding a Mockery::mock('\\Illuminate\\Auth\\Reminders\\PasswordBroker') - none of this helped.

How can this controller action be tested? Why is the Password facade different from Auth? What else should I try?

Thank you

So I did some more searching, coding and investigating. I finally succeeded even though it should've worked the way I first intended.

I read in Laravel documentation that calling Facade::shouldReceive('method') should return a Mockery object. So I tried this in my test:

var_dump(get_class(Auth::shouldReceive('check')));
var_dump(get_class(Password::shouldReceive('remind')));

The first one was working as expected but the Password one was not. So after reading the web a little more, walking through Laravel facades and service providers I finally came up with Something.

I mock a PasswordBroker object (that's what Password facade is referring to anyway) and "introduce it" to IoC.

$this->authReminder = Mockery::mock('Illuminate\Auth\Reminders\PasswordBroker');
App::instance('auth.reminder', $this->authReminder);

And then later I use this object instead of Password facade like this:

$this->authReminder->
    shouldReceive('remind')->
    once()->
    andReturn(Password::INVALID_USER);

I know this doesn't answer why the facade mocking doesn't work with Password but at least after many hours of struggle I'm able to write the tests I need and continue with the project.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM