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.