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

Php 控制器单元测试失败,无法检查laravel 4.2中的成功登录,php,unit-testing,laravel,laravel-4,Php,Unit Testing,Laravel,Laravel 4,我正在测试是否成功登录。为此,我正在检查 如果成功登录 应用程序应重定向到仪表板 因此,我的控制器如下所示 public function loginPost(){ if (Auth::attempt(array( 'email' => Input::get('email'), 'password' => Input::get('password') ))){ return Redirect::inten

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

  • 如果成功登录
  • 应用程序应重定向到仪表板
因此,我的
控制器
如下所示

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');
}
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');
 }
我的
测试
如下所示

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');
}
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');
 }
虽然这在浏览器中有效。但在测试过程中,它失败了,并显示以下消息:

BadMethodCallException:此模拟对象上不存在方法Mockery\u 0\u Lightning\u Auth\u AuthManager::check()


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

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

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


您还可以使用
Auth::check()
mock编写第二个测试,以返回
true
,以便测试您在登录时访问登录路径时发生的情况。

在我看来,这是一个功能测试,而不是单元测试。绝对没有必要继续模仿类。您需要为此编写一个功能测试

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');
}
如果我必须这样做,我会这样做:

    // Update the following code accordingly for your app. 

    $credentials = array(
        'email'      => 'john@example.com',
        'password'   => 'johndoe',
        'csrf_token' => csrf_token()
    );

    $this->withInput( $credentials )
        ->requestAction('POST', 'UserController@postLogin');

    $this->assertRedirection( URL::action('HomeController@getIndex') );
  • 使用用户名、密码、csrf_令牌等向登录路由发送post请求
  • 断言页面被重定向到链接假设:
    http://localhost/home
因此,您在Laravel 4.2中的测试代码如下:

    // Update the following code accordingly for your app. 

    $credentials = array(
        'email'      => 'john@example.com',
        'password'   => 'johndoe',
        'csrf_token' => csrf_token()
    );

    $this->withInput( $credentials )
        ->requestAction('POST', 'UserController@postLogin');

    $this->assertRedirection( URL::action('HomeController@getIndex') );
也许,这会有所帮助


作为旁白:我同意@Raza Mehdi

我认为从高层测试登录功能,是测试我们的实际代码,而不是模拟
Auth
对象(我们不拥有的类型)

  • 调用登录路由,传递用户凭据
  • 断言状态为OK
  • 断言用户已重定向到仪表板
代码:

 $input = [...];

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

 $this->assertResponseStatus(200);

 $this->assertRedirectedToRoute('dashboard');

你能粘贴完整的测试吗class@NirmalzThapaz看起来好像你是如何模仿
Auth
对象的——你能在哪里发布你的模仿(或整个测试用例文件)?就像@Leith问的,你是在模仿
Auth
对象吗?