Unit testing your API in Laravel

Unit testing your API in LaravelUnit testing your API in LaravelMark ScherrenbergBlockedUnblockFollowFollowingAug 5, 2018So let’s say you’ve build an API, but want to take it a step further by testing it.

Well, Laravel makes it very easy.

At first, let’s set-up a new Laravel enviroment.

I’m using Laravel’s 5.

6 version for this article.

Install Laravel (https://laravel.

com/docs/5.

6#installation)Set-up Laravel, create your database and make it accessible by configuring the .

env file in your project root directory.

After laravel is installed make sure phpunit is installed on your machine.

You can install it here: https://phpunit.

de/getting-started/phpunit-7.

html.

After installing phpunit, enter the following command in your terminal pointing at your laravel’s project root directory.

phpunitIf every is set-up properly you should get something like:PHPUnit 7.

3.

0 by Sebastian Bergmann and contributors.

2 / 2 (100%)Time: 1.

12 seconds, Memory: 12.

00MBOK (2 tests, 2 assertions)Now head over to /.

phpunit.

xml and override the database connection and disable the APP_DEBUG configuration of the .

env file.

So phpunit will use sqlite.

Add the following in the <php> section:<env name="DB_CONNECTION" value="sqlite"/><env name="APP_DEBUG" value="false"/>So it should look like this:.

<php> <env name="APP_ENV" value="testing"/> <env name="BCRYPT_ROUNDS" value="4"/> <env name="CACHE_DRIVER" value="array"/> <env name="SESSION_DRIVER" value="array"/> <env name="QUEUE_DRIVER" value="sync"/> <env name="MAIL_DRIVER" value="array"/> <env name="DB_CONNECTION" value="sqlite"/> <env name="APP_DEBUG" value="false"/></php>.

Let’s create a new Model called Post with:php artisan make:model Post -c -m -fAdding -c, -m, -f after the model name will also generate a controller, migration and factory file.

Head over to the migration file and add a few lines at the up() method:public function up(){ Schema::create('posts', function (Blueprint $table) { $table->increments('id'); $table->string('title'); $table->text('content'); $table->timestamps(); });}Then in /database/factories/PostFactory.

php add a few lines:<?phpuse FakerGenerator as Faker;$factory->define(AppPost::class, function (Faker $faker) { return [ 'title' => $faker->sentence, 'content' => $faker->paragraph ];});When the Post factory is set-up go to the Post model /app/Post.

php and add protected fillable to be able to use the create method:<?phpnamespace App;use IlluminateDatabaseEloquentModel;class Post extends Model{ protected $fillable = [ 'title', 'content' ];}In /app/Http/Controllers/PostController.

php and add some basic crud methods for testing purpose:<?phpnamespace AppHttpControllers;use AppPost;use IlluminateHttpRequest;class PostController extends Controller{ public function index() { return Post::all(); } public function show(Post $post) { return $post; } public function store(Request $request) { $post = Post::create($request->all()); return response()->json($post, 201); } public function update(Request $request, Post $post) { $post->update($request->all()); return response()->json($post); } public function delete(Post $post) { $post->delete(); return response()->json(null, 204); }}Index (Returns all posts)Show (Returns a single posted based on the id in the parameter)Store (Returns the created post with a 201 status code, meaning: ‘Content created’)Update (Returns the updated post with the default 200 status code)Delete (Returns null with a 204 status code, meaning: ‘No content’)Read more about status codes: https://httpstatuses.

com/In /routes/api.

php add some routes to use our controller:Be aware that there is no authentication on any of the routes currently.

All routes in /api.

php will be prefixed with /apiIn the group I prefixed all underlaying routes with /posts.

So for instance to request the first route, you would call: /api/postsThen run the migration file using:php artisan migrateLaravel ships with two test classes located in /tests/Feature and /tests/Unit.

We’ll start by editing /tests/TestCase.

php to:Use the following command to generate a new unit test file:php artisan make:test PostTest –unitOpen the generated file /tests/Unit/PostTest.

php and add the testing methods:Every test has his own method prefixed with test, this is required for phpunit to find and use the test method.

We’re checking if the expected status codes are returned with assertStatusWith assertJson we’re testing if the JSON result matches our expectation.

In test_can_list_posts we’re removing all attributes of each post created so we’ll only have ‘id’, ‘title’ and ‘content’.

And then we check that all items in the returned JSON array by the API contain ‘id’, ‘title’, ‘content’ by using assertJsonStructure.

To test, let’s run phpunit in the terminal:phpunitThat’s it!.It should pass all tests.

Feel free to contact me if you have any questions or improvements, I’m happy to help.

.

. More details

Leave a Reply