Testing Helpers in Laravel 5.4

These are some helper methods and settings to make writing tests in Laravel easier, more clear and less verbose. We’re following along from the amazing Laracast episode.

We are going to add some helper functions in a file that load for our tests in development. To do that head into composer.json and add the following:

"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
},
"files": ["tests/utilities/functions.php"]
},

We then create tests/utilities/functions.php and folder in our Laravel 5.4 application and include a couple helper methods for creating records and making new records. The create command will persist the records to the database. The make command will make instances of the records but not persist to database. There are more details about our tests in the last post.

<?php
function create($class, $attributes = [])
{
return factory($class)->create($attributes);
}
function make($class, $attributes = [])
{
return factory($class)->make($attributes);
}

This file will only be loaded for development. Run the dump-autoload command to rerun our composer.json file. Then run phpunit command to make sure all of our tests still pass.

$ composer dump-autoload
$ phpunit

We can then refactor our test code from:

$thread = factory(‘App\Thread’)->make();

to:

$thread = make(‘App\Thread’);

and from:

$reply = factory('App\Reply')->create(['thread_id' => $this->thread->id]);

to:

$reply = create('App\Reply', ['thread_id' => $this->thread->id]);

In the last post we had the following line to create a user and set the current authentication session to that user. The line below signs a user in so we can test the authentication and security features for our application:

$this->actingAs(factory('App\User')->create());

instead of doing that we would like to do:

$this->signIn();

To make that happen add the following to tests/TestCase.php:

<?php
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
use CreatesApplication;
    protected function signIn($user = null)
{
// use passed in user or create one
$user = $user ?: create('App\User');
$this->actingAs($user);
return $this;
}
}

This method adds the signIn functionality we need and makes writing tests easier and less verbose.

Turning on and off exception handling

There is an issue in Laravel 5.4 with toggling on and off the exception handling. Adam Wathan has a fix here, adding functions to run tests with and without exception handling.

That’s what I got! Do you use tests in Laravel? What issues have you encountered? Feedback much appreciated. Thank you


I am following from the Laracasts series: Let’s Build A Forum with Laravel and TDD

This is the fifth tutorial working on this app.
Part 1, Part 2, Part 3, Part 4
The source code is available on github

Thanks for reading!

Update 04/04/2018:

I’ve been following Adam Wathan’s Test Driven Development course for Laravel 5. In one of the initial videos he outlines how to use SQLite in memory database for phpunit testing in Laravel. Add these two lines to the bottom of phpunit.xml

<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>

Additionally, to write tests following the video (i.e. the old way before Dusk was introduced in Laravel 5.4) I used the: laravel/browser-kit-testing package.