Home » Php » Laravel Testing – Throwing exception with Mockery

Laravel Testing – Throwing exception with Mockery

Posted by: admin December 2, 2021 Leave a comment

Questions:

I’m very new to Laravel and unit testing in general. I’m trying to write some tests for my AccountController and I’ve run into a road block.

I’m using Sentry to handle users and groups in the site. I’m trying to test that my controller is handling exceptions thrown by Sentry properly. So my controller method that handles the login POST looks like this:

public function postLogin(){

    $credentials = array(
        'email' => Input::get('email'),
        'password' => Input::get('password')
    );

    try{
        $user = $this->authRepo->authenticate($credentials, true);
        return Redirect::route('get_posts');
    }
    catch (Exception $e){
        $message = $this->getLoginErrorMessage($e);
        return View::make('login', array('errorMsg' => $message));
    }
}

authRepository is just a repository that uses Sentry to handle authentication. Now I want to test that when an email address is not specified a LoginRequiredException is thrown and the user sees the error message. Here is my test:

public function testPostLoginNoEmailSpecified(){

    $args = array(
        'email' => '[email protected]'
    );

    $this->authMock
        ->shouldReceive('authenticate')
        ->once()
        ->andThrow(new Cartalyst\Sentry\Users\LoginRequiredException);

    $this->action('POST', 'MyApp\Controllers\[email protected]', $args);

    $this->assertViewHas('errorMsg', 'Please enter your email address.');
}

However, the test is not passing. For some reason all it spits out is:

There was 1 error:

1) AccountControllerTest::testPostLoginNoEmailSpecified
Cartalyst\Sentry\Users\LoginRequiredException: 

Am I using the andThrow() method incorrectly? If anyone can shed any light on what is going on it would be much appreciated.

Thanks in advance!

Answers:

So I actually just figured the problem out. Turns out it wasn’t a problem with my unit tests at all but was actually just a namespacing issue. I forgot the backslash on the Exception class. So in my controller it should have been:

try{
    $user = $this->authRepo->authenticate($credentials, true);
    return Redirect::route('get_posts');
}
catch (\Exception $e){
    $message = $this->getLoginErrorMessage($e);
    return View::make('account.login', array('errorMsg' => $message));
}