Testing the index page

To test the index page we need to create an article, send a get request to the articles index route, assert it is successful and that we can see the title on the page.

<?php

namespace Tests\Feature;

use Tests\TestCase;

class ArticleIndexTest extends TestCase
{
    public function testViewIndex()
    {
        factory(Article::class)->create([
            'title' => 'My first news article',
            'private' => 'false'
        ]);

        $response = $this->get(route('articles.index'));
        $response->assertSuccessful();
        $response->assertSee('My first news article');
    }
}

This seems nice and simple so far. The scenario set up is just a factory creating a new article.

Next, we want to add a new test to check that guest users can’t see a private article.

public function testCannotSeePrivateArticle()
{
    factory(Article::class)->create([
        'title' => 'My first private article',
        'private' => true
    ]);

    $response = $this->get(route('articles.index'));
    $response->assertSuccessful;
    $response->assertDontSee('My first private article');
}

Let’s say that the business now wants to add draft and published article status as well. We could update our tests with this additional column when making the articles like this.

factory(Article::class)->create([
    'title' => 'My first private article',
    'private' => true,
    'published' => true
]);

This seems fine, but the set up is starting to grow bit by bit. One way of taking this out of individual tests is to create some factory states.

Using Factories States in Tests

Factory states allow you to overwrite the default values you specify in your factory. You may have a factory like this where it randomly selects whether a post is private or public when it is created, or have it always set the published value to false.

use Faker\Generator as Faker;

$factory->define(App\Article::class, function (Faker $faker) {
    return [
        'title' => $faker->words(3, true),
        'private' => $faker->boolean(),
        'published' => false
    ]
});

With factories you can also define a state, such as private or published.

use Faker\Generator as Faker;

$factory->define(App\Article::class, function (Faker $faker) {
    return [
        'title' => $faker->words(3, true),
        'private' => $faker->boolean(),
        'published' => false
    ]
});

$factory->state(App\Article::class, 'public', [
    'private' => false
]);

$factory->state(App\Article::class, 'private', [
    'private' => true
]);

$factory->state(App\Article::class, 'published', [
    'published' => true
]);

#laravel #webdev #php #testing #keep tests

Keeping Tests Simple in Laravel
1.30 GEEK