控制器的单元测试失败,以检查laravel 4.2中的成功登录

Nir*_*paz 9 php unit-testing laravel laravel-4

我正在测试是否成功登录.为此,我正在检查,

  • 如果成功登录
  • 应用程序应重定向到仪表板

为此,我controller看起来像这样

public function loginPost(){

    if (Auth::attempt(array(
        'email'     => Input::get('email'),
        'password'  => Input::get('password')
    ))){
        return Redirect::intended(route('dashboard'));
    }

    return Redirect::route('login')             
                        ->withInput()
                        ->with('errorMessage', 'Failed');
}
Run Code Online (Sandbox Code Playgroud)

test看起来像这样

public function testLoginSuccess(){
     $input = [
         'email'                 => 'xyz@gmail.com',
         'password'              => 'computer'
     ];

     Input::replace($input);

     Auth::shouldReceive('attempt')
           ->with($input)
           ->once()
           ->andReturn(true);

     $this->call('POST', 'login', $input);

     $this->assertRedirectedToRoute('dashboard');
 }
Run Code Online (Sandbox Code Playgroud)

虽然这适用于浏览器.但在测试时,它失败并显示以下消息:

BadMethodCallException:方法Mockery_0_Illuminate_Auth_AuthManager :: check()在此模拟对象上不存在

pat*_*cus 1

您没有显示路线的定义,但我假设您的login路线受到guestbefore 过滤器的保护。Auth::check()此过滤器在分派到路由之前使用。

在您的测试中,当您调用 时Auth::shouldReceive(),这会使Auth外观指向一个模拟实例。由于您没有为该check()方法的模拟实例定义期望,因此您会收到错误。

最简单的解决方案是继续模拟该Auth::check()方法,然后让它返回false(模拟在未登录时访问该路线)。

public function testLoginSuccess() {
    $input = [
        'email' => 'xyz@gmail.com',
        'password' => 'computer'
    ];

    Input::replace($input);

    // Tell Auth we're not logged in.
    Auth::shouldReceive('check')
        ->once()
        ->andReturn(false);

    Auth::shouldReceive('attempt')
        ->with($input)
        ->once()
        ->andReturn(true);

    $this->call('POST', 'login', $input);

    $this->assertRedirectedToRoute('dashboard');
}
Run Code Online (Sandbox Code Playgroud)

您还可以使用Auth::check()mocked to return编写第二个测试true,以测试当您在已经登录的情况下访问登录路由时会发生什么。