How to Test Controller in Laravel: Simple Guide with Examples
To test a controller in Laravel, create a feature test using
php artisan make:test and use HTTP methods like get() or post() to call controller routes. Then assert the response status, view, or JSON data to verify controller behavior.Syntax
Laravel controller tests are usually written as feature tests. You use HTTP verbs like get(), post(), put(), or delete() to simulate requests to your controller routes. Then you use assertion methods to check the response.
$this->get('/url'): Simulates a GET request.$this->post('/url', [data]): Simulates a POST request with data.assertStatus(200): Checks if response status is 200 OK.assertViewIs('view.name'): Checks if a specific view is returned.assertJson([...]): Checks if JSON response contains expected data.
php
<?php namespace Tests\Feature; use Tests\TestCase; class ExampleControllerTest extends TestCase { public function test_index_returns_view() { $response = $this->get('/example'); $response->assertStatus(200); $response->assertViewIs('example.index'); } }
Example
This example shows how to test a simple controller method that returns a view with data. It sends a GET request to the route, checks the HTTP status, verifies the view name, and confirms the view has expected data.
php
<?php namespace Tests\Feature; use Tests\TestCase; class UserControllerTest extends TestCase { public function test_show_user_profile() { $response = $this->get('/user/1'); $response->assertStatus(200); $response->assertViewIs('user.profile'); $response->assertViewHas('user'); } }
Output
PASS Tests\Feature\UserControllerTest
✓ test_show_user_profile
Common Pitfalls
Common mistakes when testing controllers in Laravel include:
- Not setting up test data before calling the controller, causing tests to fail due to missing data.
- Using
assertSee()on JSON responses instead ofassertJson(). - Forgetting to run migrations or seeders in the test environment.
- Testing private methods instead of public controller actions.
php
<?php // Wrong: Testing private method directly // public function test_private_method() { // $controller = new UserController(); // $result = $controller->privateMethod(); // Not recommended // } // Right: Test public route behavior public function test_user_index() { $response = $this->get('/user'); $response->assertStatus(200); }
Quick Reference
| Method | Purpose |
|---|---|
| $this->get('/url') | Simulate GET request to controller route |
| $this->post('/url', [data]) | Simulate POST request with data |
| assertStatus(200) | Check HTTP response status is OK |
| assertViewIs('view.name') | Verify returned view name |
| assertViewHas('key') | Check view has specific data |
| assertJson([...]) | Verify JSON response content |
Key Takeaways
Use Laravel feature tests with HTTP methods to test controller routes.
Assert response status, view, or JSON to verify controller output.
Prepare test data and environment before running controller tests.
Avoid testing private controller methods directly; test public routes instead.
Use Laravel's built-in assertion methods for clear and readable tests.