2

I'm starting out with some TDD in Laravel 4. While I understand the basics of dependency injection, I can't seem to get my head around how to mock the Auth functionality. Below is my current user controller with just the index method and it's applicable test. The current setup keeps throwing me errors when I run phpunit, namely "undefined index" errors for Auth. Is there a better way of doing this?

My Controller:

class UserController extends \BaseController {

    /**
     * User instance
     * 
     * @var User
     */
    protected $user;

    /**
     * The master layout that View's will be built upon.
     * 
     * @var string
     */
    protected $layout = 'layout.user-master';

    /**
     * Constructor
     * 
     * @param User $user
     * @param View $view
     */
    public function __construct(User $user) 
    {
        $this->user = $user;

        // Filters
        $this->beforeFilter('csrf', array('on' => 'post'));
        $this->beforeFilter('auth', array('except' => array('create', 'store')));
    }

    /**
     * Display a listing of the user.
     *
     * @return Response
     */
    public function index()
    {
        $id = Auth::user()->id;

        $user = $this->user->find($id);

        $this->layout->content = View::make('user.index', compact('user'));
    }
}

User Controller Test

<?php

use \Mockery;

class UserControllerTest extends TestCase {

    public function __construct()
    {
        // Mock an Eloquent User Model instance
        $this->mock = Mockery::mock('Eloquent', 'User');    
    }

    public function tearDown()
    {
        Mockery::close();
    }

    public function testIndex()
    {
        Auth::shouldReceive('user')->once()->andReturn(Mockery::any());

        $this->mock
                ->shouldReceive('find')
                ->once()
                ->with(Mockery::any())
                ->andReturn('foo');

        $this->app->instance('User', $this->mock);

        $this->call('GET', 'user');

        $this->assertViewHas('user');
    }

}
2
  • did you ever work around this? Commented Dec 17, 2013 at 5:48
  • Yes, I've added the answer I found to this question now. Commented Dec 18, 2013 at 21:24

1 Answer 1

5

I've found the solution to this issue.

All I had to do is call the be() method in my test to set the currently logged in user.

$this->be(User::find(1));
Sign up to request clarification or add additional context in comments.

2 Comments

isn't that coupling the test to your database? Why not use $user = Auth::user(); ? It returned the mock user too.
maybe $user = new User(['name' => 'Test']); $this->be($user) works better

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.