- Introduction
- Defining & Running Tests
- Test Environment
- Calling Routes From Tests
- Mocking Facades
- Framework Assertions
- Helper Methods
- Refreshing The Application
Laravel is built with unit testing in mind. In fact, support for testing with PHPUnit is included out of the box, and a phpunit.xml
file is already setup for your application. In addition to PHPUnit, Laravel also utilizes the Symfony HttpKernel, DomCrawler, and BrowserKit components to allow you to inspect and manipulate your views while testing, allowing to simulate a web browser.
An example test file is provided in the app/tests
directory. After installing a new Laravel application, simply run phpunit
on the command line to run your tests.
To create a test case, simply create a new test file in the app/tests
directory. The test class should extend TestCase
. You may then define test methods as you normally would when using PHPUnit.
class FooTest extends TestCase {
public function testSomethingIsTrue()
{
$this->assertTrue(true);
}
}
You may run all of the tests for your application by executing the phpunit
command from your terminal.
Note: If you define your own
setUp
method, be sure to callparent::setUp
.
When running unit tests, Laravel will automatically set the configuration environment to testing
. Also, Laravel includes configuration files for session
and cache
in the test environment. Both of these drivers are set to array
while in the test environment, meaning no session or cache data will be persisted while testing. You are free to create other testing environment configurations as necessary.
You may easily call one of your routes for a test using the call
method:
$response = $this->call('GET', 'user/profile');
$response = $this->call($method, $uri, $parameters, $files, $server, $content);
You may then inspect the Illuminate\Http\Response
object:
$this->assertEquals('Hello World', $response->getContent());
You may also call a controller from a test:
$response = $this->action('GET', 'HomeController@index');
$response = $this->action('GET', 'UserController@profile', array('user' => 1));
The getContent
method will return the evaluated string contents of the response. If your route returns a View
, you may access it using the original
property:
$view = $response->original;
$this->assertEquals('John', $view['name']);
To call a HTTPS route, you may use the callSecure
method:
$response = $this->callSecure('GET', 'foo/bar');
Note: Route filters are disabled when in the testing environment. To enable them, add
Route::enableFilters()
to your test.
You may also call a route and receive a DOM Crawler instance that you may use to inspect the content:
$crawler = $this->client->request('GET', '/');
$this->assertTrue($this->client->getResponse()->isOk());
$this->assertCount(1, $crawler->filter('h1:contains("Hello World!")'));
For more information on how to use the crawler, refer to its official documentation.
When testing, you may often want to mock a call to a Laravel static facade. For example, consider the following controller action:
public function getIndex()
{
Event::fire('foo', array('name' => 'Dayle'));
return 'All done!';
}
We can mock the call to the Event
class by using the shouldReceive
method on the facade, which will return an instance of a Mockery mock.
public function testGetIndex()
{
Event::shouldReceive('fire')->once()->with('foo', array('name' => 'Dayle'));
$this->call('GET', '/');
}
Note: You should not mock the
Request
facade. Instead, pass the input you desire into thecall
method when running your test.
Laravel ships with several assert
methods to make testing a little easier:
public function testMethod()
{
$this->call('GET', '/');
$this->assertResponseOk();
}
$this->assertResponseStatus(403);
$this->assertRedirectedTo('foo');
$this->assertRedirectedToRoute('route.name');
$this->assertRedirectedToAction('Controller@method');
public function testMethod()
{
$this->call('GET', '/');
$this->assertViewHas('name');
$this->assertViewHas('age', $value);
}
public function testMethod()
{
$this->call('GET', '/');
$this->assertSessionHas('name');
$this->assertSessionHas('age', $value);
}
public function testMethod()
{
$this->call('GET', '/');
$this->assertSessionHasErrors();
// Asserting the session has errors for a given key...
$this->assertSessionHasErrors('name');
// Asserting the session has errors for several keys...
$this->assertSessionHasErrors(array('name', 'age'));
}
public function testMethod()
{
$this->call('GET', '/');
$this->assertHasOldInput();
}
The TestCase
class contains several helper methods to make testing your application easier.
$this->session(['foo' => 'bar']);
$this->flushSession();
You may set the currently authenticated user using the be
method:
$user = new User(array('name' => 'John'));
$this->be($user);
You may re-seed your database from a test using the seed
method:
$this->seed();
$this->seed($connection);
More information on creating seeds may be found in the migrations and seeding section of the documentation.
As you may already know, you can access your Laravel Application
/ IoC Container via $this->app
from any test method. This Application instance is refreshed for each test class. If you wish to manually force the Application to be refreshed for a given method, you may use the refreshApplication
method from your test method. This will reset any extra bindings, such as mocks, that have been placed in the IoC container since the test case started running.