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 my previous article, I had explained why should we use Laravel factories. You can check the article at Factories To Speed Up Test-Driven Development In Laravel.
In this article let's see how we can use Factory states to write fluent test cases.
First, let's see how does our test cases look like without any factory states. Basically, we are writing a test to check that the user cannot view any unpublished blog posts.
/**
* @test
*/
public function user_cannot_view_unpublished_post()
{
$post = Post::factory()->create([
'published_at' => null
]);
$resource = $this->get("/posts/" . $post->slug);
$resource->assertStatus(404);
}
public function definition() {
$title = $this->faker->title;
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'),
];
}
/**
* @test
*/
public function user_cannot_view_unpublished_post()
{
$post = factory(Post::class)->create([
'published_at' => null
]);
$resource = $this->get("/posts/" . $post->slug);
$resource->assertStatus(404);
}
$factory->define(Post::class, function (Faker $faker) {
$title = $faker->title;
return [
'title' => $title,
'slug' => Str::slug($title),
'summary' => $faker->paragraph,
'body' => $faker->paragraph,
'author_id' => function () {
return factory(User::class)->create()->id;
},
];
});
Basically, there is no problem with the above approach. Since we can write more cleaner we can use this approach.
From the above code snippet, we can write the code
/**
* @test
*/
public function user_cannot_view_unpublished_post()
{
$post = Post::factory()->states(['unpublished'])->create();
$resource = $this->get("/posts/" . $post->slug);
$resource->assertStatus(404);
}
use App\Post;
use App\User;
use Carbon\Carbon;
use Illuminate\Support\Str;
use Faker\Generator as Faker;
public function definition(){
$title = $this->faker->title;
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'),
];
}
public function unpublished()
{
return $this->state(function (array $attributes) {
return [
'published_at' => null
];
});
}
public function published()
{
return $this->state(function (array $attributes) {
return [
'published_at' => Carbon::parse('-1 week')
];
});
}
$post = factory(Post::class)->create([
'published_at' => null
]);
$post = factory(Post::class)->states(['unpublished'])->create();
Now your test case will look like the following very lean, clean & fluent
/**
* @test
*/
public function user_cannot_view_unpublished_post()
{
$post = factory(Post::class)->states(['unpublished'])->create();
$resource = $this->get("/posts/" . $post->slug);
$resource->assertStatus(404);
}
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' => $title,
'slug' => Str::slug($title),
'summary' => $faker->paragraph,
'body' => $faker->paragraph,
'author_id' => function () {
return factory(User::class)->create()->id;
},
];
});
$factory->state(Post::class, 'unpublished', function (Faker $faker) {
return [
'published_at' => null
];
});
/** Similarly you can have published state too */
$factory->state(Post::class, 'published', function (Faker $faker) {
return [
'published_at' => Carbon::parse('-1 week')
];
});
I hope this article helped you. Please share it with your friends.
Accessors And Mutators In PHP Laravel
PHP extension ext-intl * is missing
Push Files To CPanel / Remote Server using FTP Software FileZilla
composer.json v/s composer.lock
URL Redirects From Called Functions In Laravel
Laravel Custom Maintenance Page
Custom Validation Rules In PHP Laravel (Using Artisan Command)
Supervisor For Laravel Queue Scheduling
Client-Side Form Validation With Javascript
Free SSL Certificate With Lets Encrypt/Certbot In Linux (Single / Multiple Domains)
@stack @push and @prepend In Laravel Blade