rshepard21's avatar

Need to Test for Duplicate Slugs

I am trying to create a unit test for duplicate slugs, I am using the following code to test:

public function a_post_cannot_have_a_duplicate_slug()
    {
        $post = factory('App\Post')->raw();

        $this->assertDatabaseMissing('posts', $post);
    }

I cannot for my own life figure out what I need to do to check for if a slug already exists in testing.

Help is very much appreciated, Thank you bunches.

0 likes
5 replies
piljac1's avatar

For this kind of test you need to avoid using factory to know what to expect (in case you encounter a bug one day).

  1. Create a post with manual data
  2. Create an array containing key/values representing your columnName/value pairs in your post model. Make sure these values differ from the first post, except for the slug (so it is easy to distinguish).
  3. Call your store route and pass your array to it.
  4. Assert that the second post wasn't inserted

That would be the simple way, but you could also replace the 4th step by retrieving the count of the posts having the specified slug and assert that the count is 1

piljac1's avatar

It's also important to note that unit tests should test your code (validation of the store route in your case) and not pre-built functionalities such as the database unique constraint or the factory implementation (except if you want to test that your factories are still up to date as you grow and add column to the model).

rshepard21's avatar

Would something like this maybe work?

/** @test */
    public function a_post_cannot_have_a_duplicate_slug()
    {
        $post = factory('App\Post')->raw();

        $this->post('/blog', $post)
            ->assertRedirect('/blog');

        $post2 = [
            'title' => $this->faker->sentence,
            'body' => $this->faker->paragraph,
            'slug' => $post['slug']
        ];

        $this->post('/blog', $post2);

        $this->assertDatabaseMissing('posts', $post);
    }
piljac1's avatar
piljac1
Best Answer
Level 28

Yes (even though I'm not a fan of faker in unit tests like I said). But you would have to change $post by $post2 in your assertion.

STEREOH's avatar

Small mistake on the last line.

You want to assert you're missing $post2 , not $post

$this->assertDatabaseMissing('posts', $post2);

edit: oops didn't refresh the page see @piljac1 answer haha

Please or to participate in this conversation.