PHPUnit is well integrated with Laravel 5 as it was with Laravel 4, so it is rather easy to set up the testing environment. A good method for testing would be to use the SQLite database and to set it up to reside in the memory, but you need to modify the config/database.php
file, as follows:
'default' => 'sqlite', 'connections' => array( 'sqlite' => array( 'driver' => 'sqlite', 'database' => ':memory:', 'prefix' => '', ), ),
Then, we need to modify the phpunit.xml
file to set a DB_DRIVER
environment variable:
<php> <env name="APP_ENV" value="testing"/> <env name="CACHE_DRIVER" value="array"/> <env name="SESSION_DRIVER" value="array"/> <env name="DB_DRIVER" value="sqlite"/> </php>
Then, we need to modify the following line in the config/database.php
file:
'default' => 'mysql',
We modify the preceding line to match with the following line:
'default' => env('DB_DRIVER', 'mysql'),
Now, we will set up PHPUnit to run our migrations on the in-memory sqlite
database.
In the tests
directory, there are two classes: a TestCase
class that extends the LaravelTestCase
class and an ExampleTest
class that extends the TestCase
class.
We need to add two methods to TestCase
to perform the migrations, run the seeder, and then revert the database back to its original state:
<?php class TestCase extends IlluminateFoundationTestingTestCase { public function setUp() { parent::setUp(); Artisan::call('migrate'), Artisan::call('db:seed'), } /** * Creates the application. * * @return IlluminateFoundationApplication */ public function createApplication() { $app = require __DIR__.'/../bootstrap/app.php'; $app->make('IlluminateContractsConsoleKernel')->bootstrap(); return $app; } public function tearDown() { Artisan::call('migrate:rollback'), } }
Now, we will create a PHPUnit test to verify that the data is being saved correctly in the database. We need to modify tests/ExampleTest.php
to the following code:
<?php class ExampleTest extends TestCase { /** * A basic functional test example. * * @return void */ public function testReserveRoomExample() { $reservationRepository = new MyCompanyAccommodationReservationRepository( new MyCompanyAccommodationReservation()); $reservationValidator = new MyCompanyAccommodationReservationValidator(); $start_date = '2015-10-01'; $end_date = '2015-10-10'; $rooms = MyCompanyAccommodationRoom::take(2)->lists('id')->toArray(); if ($reservationValidator->validate($start_date,$end_date,$rooms)) { $reservation = $reservationRepository->create(['date_start'=>$start_date,'date_end'=>$end_date,'rooms'=>$rooms,'reservation_number'=>'0001']); } $this->assertInstanceOf('MyCompanyAccommodationReservation',$reservation); $this->assertEquals('2015-10-01',$reservation->date_start); $this->assertEquals(2,count($reservation->rooms)); }
To start PHPUnit, simply type the following command:
$ phpunit
The tests will be run. Since the create
method of the Reservation
class returns a reservation, we may use the assertInstanceOf
method of PHPUnit to determine whether or not a reservation was created in the database. We can add any other assertions to make sure that the values saved are exactly what we intended. For example, we can assert that the start date is equal to '2015-10-01'
and the size of the room
array is equal to two
. Together with the testBasicExample()
method, we can ensure that a GET
request to "/"
returns a 200
. The PHPUnit results will look like this:
Notice that there were two dots to represent the tests. OK means that nothing failed, and we are told again that there were two tests and four assertions; one assertion in the example and the other three, which we have added to our testReserveRoomExample
test. Had we tested that there were three rooms instead of two, PHPUnit would have produced the following output:
$ phpunit PHPUnit 4.5.0 by Sebastian Bergmann and contributors. Configuration read from /var/www/laravel.example/phpunit.xml . F Time: 1.59 seconds, Memory: 10.75Mb There was 1 failure: 1) ExampleTest::testReserveRoomExample Failed asserting that 2 matches expected 3. /var/www/laravel.example/tests/ExampleTest.php:24 FAILURES! Tests: 2, Assertions: 4, Failures: 1.
Notice that instead of the second dot, we have an F
for failure, and instead of OK
, we're told that there was 1
failure. PHPUnit then lists which tests failed, and nicely tells us the line that I deliberately modified to be incorrect, as follows:
$this->assertEquals(3,count($reservationResult->rooms));
The preceding line is indeed incorrect:
Failed asserting that 2 matches expected 3.
Remember that 2
is the value of the count ($reservationResult->rooms)
.