Good content takes time and effort to come up with.

Please consider supporting us by just disabling your AD BLOCKER and reloading this page again.







Factories To Speed Up Test-Driven Development In Laravel | StackCoder


Factories To Speed Up Test-Driven Development In Laravel


Share On     Share On WhatsApp     Share On LinkedIn


In this article, I will explain how to use Laravel Factories for faster-test-driven development and supercharge your test cases.


Bad Approach: As We Repeat The Code


Think that we are creating a blog and we are testing to make sure that user must not view unpublished posts then we might have the following test code:


NOTE: Creating User ie $author for post in this test was not necessary, but if anyone interested to know how foreign keys are tested then it will help them.


tests / Feature / PostsTest

use Illuminate\Support\Str;
use Carbon\Carbon;

/**
* @test
*/
public function user_cannot_view_unpublished_post()
{
    $author = User::create([
        'name'      => 'John Doe',
        'email'     => 'john@example.com',
        'password'  => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi'
    ]);

    $title = 'My first blog';
    $post = Post::create([
        'title'         => $title,
        'slug'          => Str::slug($title),
        'summary'       => 'First blog summary',
        'body'          => 'First blog body',
        'author_id'     => $author->id,
        'published_at'  => null
    ]);

    $resource = $this->get("/posts/" . $post->slug);

    $resource->assertStatus(404);
}


The code looks perfectly fine. But the issue is we are filling up the Post & Author details manually.


In this particular feature test we are least concerned about the author details & in Posts only concerned about published_at.


Better Approach: Omit The Repeating Code With factory


Now lets refactor the above code by using factories.


Why Factories?

When performing testing, you may need to insert a few records into your database before executing your test. Instead of manually specifying the value of each column when you create this test data, Laravel allows you to define a default set of attributes for each of your Eloquent models using model factories.


Already Laravel comes with User Factory, just in case if you have deleted then you can use the following command to generate one


database / factories / UserFactory.php

php artisan make:factory UserFactory --model=User


Factory Code

$factory->define(User::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'email_verified_at' => now(),
        'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
        'remember_token' => Str::random(10),
    ];
});

database / factories / PostFactory.php

php artisan make:factory PostFactory --model=Post


Factory Code

use App\Post;
use App\User;
use Carbon\Carbon;
use Illuminate\Support\Str;
use Faker\Generator as Faker;

$factory->define(Post::class, function (Faker $faker) {
    return [
        'title'         => 'My first blog',
        'slug'          => Str::slug('My first blog'),
        'summary'       => 'First blog summary',
        'body'          => 'First blog body',
        'author_id'     => function () {
            return factory(User::class)->create()->id;
        },
        'published_at'  => Carbon::parse('-1 week')
    ];
});


Now our refactored test case looks like the following


tests / Feature / PostsTest

/**
* @test
*/
public function user_cannot_view_unpublished_post()
{
    $author = factory(User::class)->create();

    $post = factory(Post::class)->create([
        'author_id'     => $author->id,
        'published_at'  => null
    ]);
    $resource = $this->get("/posts/" . $post->slug);

    $resource->assertStatus(404);
    /** Assertion to check for author, but not necessary */
}


Very clean right.


Conclusion


I hope this article helped you. Please share it with your friends.


Stripe Payment Integration With Laravel

Writing Clean Code In PHP

Foreign Key Migrations Simplified In Laravel 7.x

Global Data In All Laravel Blade Pages

Select2 Dropdown

Observers In Laravel

Relationship Table Data With Route Model Binding In Laravel

Getting Started With AMP (Accelerated Mobile Pages)

Setup AMP (Accelerated Mobile Pages) In PHP Laravel

Add Analytics To AMP (Accelerated Mobile Pages) HTML Pages

Add Google ADS In AMP (Accelerated Mobile Pages) Website







Author Image
AUTHOR

Channaveer Hakari

I am a full-stack developer working at WifiDabba India Pvt Ltd. I started this blog so that I can share my knowledge and enhance my skills with constant learning.

Never stop learning. If you stop learning, you stop growing