Unit Testing Laravel 4 w/ Cartalyst Sentry + Mockery
Joe • June 26, 2014
php testing laravelI had a really hard time piecing this together so I thought I'd share it and maybe it would help someone (or me in 2 months when I forget all of this and stumble upon it again).
The use case: I have a Controller "BoxesController" that I want to unit test the store() method on. The thing I had to play with some was having the test act as an admin user because I was posting to a route only admins should be able to access.
The key to this is to set the user in the test to the user who should have access to post to our route (an Administrator).
...
$user = Sentry::findUserByID(1);
Sentry::setUser($user);
...
Something else that tripped me up was even though I was passing $input into the $this->mock...
...
$this->mock
->shouldReceive('create')
->once()
->with($input);
...
I still had to pass $input to $this->call before the controller would see any input...
...
$this->app->instance('Box', $this->mock);
$this->call('POST', 'admin/boxes', $input);
...
Here is My BoxesControllerTest.php
class BoxesControllerTest extends TestCase {
public function setUp()
{
parent::setUp();
$this->mock = Mockery::mock('Eloquent', 'Box');
$_ENV['DB_HOST'] = 'localhost';
$_ENV['DB_NAME'] = 'homestead';
$_ENV['DB_USERNAME'] = 'homestead';
$_ENV['DB_PASSWORD'] = 'secret';
}
public function tearDown()
{
Mockery::close();
}
public function testStoreSuccess()
{
// Establish us as Admin (user_id == 1)
$user = Sentry::findUserByID(1);
Sentry::setUser($user);
Input::replace($input = ['user_id' => '2 Title',
'draft_id' => '2'
]);
$this->mock
->shouldReceive('create')
->once()
->with($input);
$this->app->instance('Box', $this->mock);
$this->call('POST', 'admin/boxes', $input);
$this->assertRedirectedToRoute('admin.boxes.index', null, ['flash']);
}
}
Here is my BoxesController
class BoxesController extends \BaseController {
protected $box;
public function __construct(Box $box)
{
$this->box = $box;
}
public function store()
{
$input = Input::all();
$rules = array(
'user_id' => 'required',
'draft_id' => 'required'
);
$validator = Validator::make($input, $rules);
if ($validator->fails()) {
return Redirect::route('admin.boxes.create')
->withErrors($validator)
->withInput($input);
} else {
$this->box->create($input);
return Redirect::route('admin.boxes.index')->with('flash', 'Your box has been created!');
}
}
Thanks for reading, hopefully this helps save you some time.
As Seen On
Recent Posts
- PHP to Rust via Copilot
- Compiling Python 3.12 from Source Tarball on Linux
- HTML Form Processing with PHP - php[architect] Magazine August 2014
- The Workshop: Local Dev with Lando - php[architect] Magazine November 2022
- Getting back into the swing of things
- All Posts
Categories
- ansible
- apache
- applesilicon
- aws
- blackwidow
- cakephp
- community
- composer
- conferences
- copilot
- data-storage
- day-job
- devops
- docker
- fpv
- general
- github
- givecamp
- homestead
- jigsaw
- joindin
- keyboard
- laravel
- learning
- linux
- maker
- mamp
- mentoring
- music
- nonprofit
- opensource
- packages
- php
- phparch
- projects
- provisioning
- python
- razer
- rust
- s3
- security
- slimphp
- speaking
- static-sites
- storage
- testing
- tiny-whoop
- today-i-learned
- training
- ubuntu
- vagrant
- version-control
- windows
- writing
- wsl
- wsl2
- zend-zray