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.
PHP extension ext-intl * is missing
What Is Laravel Resourceful Controllers?
PHP Built-In Web Server & Testing Your Development Project In Mobile Without Any Software
Comment And Like System Using Disqus
Redirect www to a non-www Website Or Vice Versa
Debugging Laravel Queue Email Issues
Facebook Login With PHP Laravel Socialite
Sass or SCSS @function vs @mixin
Run Raw Queries Securely In Laravel
Global Data In All Laravel Blade Pages
Lazy Load YouTube And Other Videos In Website