
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.
In this article, I will explain how to use Laravel Factories for faster-test-driven development and supercharge your test cases.
Think that we are creating a blog
and we are testing to make sure that users 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.
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
.
factory
Now let's refactor the above code by using 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
php artisan make:factory UserFactory --model=User
class UserFactory extends Factory
{
protected $model = User::class;
public function definition()
{
return [
'name' => $this->faker->name(),
'email' => $this->faker->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => Hash::make('password'),
'remember_token' => Str::random(10),
];
}
}
$factory->define(User::class, function (Faker $faker) {
return [
'name' => $faker->name,
'email' => $faker->unique()->safeEmail,
'email_verified_at' => now(),
'password' => Hash::make('password'),
'remember_token' => Str::random(10),
];
});
php artisan make:factory PostFactory --model=Post
class PostFactory extends Factory
{
protected $model = Post::class;
public function definition()
{
$title = $this->faker->sentence;
return [
'title' => $title,
'slug' => Str::slug($title),
'summary' => $this->faker->paragraph,
'body' => $this->faker->paragraph,
'author_id' => function () {
return User::factory()->create()->id;
},
'published_at' => Carbon::parse('-1 week')
];
}
}
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) {
$title = $faker->sentence;
return [
'title' => $title,
'slug' => Str::slug($title),
'summary' => $faker->paragraph,
'body' => $faker->paragraph,
'author_id' => function () {
return factory(User::class)->create()->id;
},
'published_at' => Carbon::parse('-1 week')
];
});
Now our refactored test case looks like the following
/**
* @test
*/
public function user_cannot_view_unpublished_post()
{
$author = User::factory()->create();
$post = Post::factory()->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 */
}
/**
* @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.
I hope this article helped you. Please share it with your friends.
Add Analytics To AMP (Accelerated Mobile Pages) HTML Pages
Create A Composer Package? Test It Locally And Add To Packagist Repository
Install NGINX In Linux / Ubuntu And Managing
Securely SSH Your Server & Push Files With FileZilla
Detect AdBlocker With Javascript And Increase Website Ads Revenue
Setup AMP (Accelerated Mobile Pages) In PHP Laravel
Generate SSH Key with ssh-keygen In Linux / Unix
Free SSL Certificate For CPanel
Lazy Load Images In Chrome With This Simple Trick
Free SSL Certificate In cPanel With ZeroSSL & Certbot
Why And How To Use PHP PDO With CRUD Examples
Laravel 7.x Multiple Database Connections, Migrations, Relationships & Querying