CamKem's avatar
Level 10

Help setting up Test checks.

Hi, I am in the process of learning TDD & I have set up an .env.testing file so that I can use sqlite for the testing db. This was all working fine, but I have a problem with one of my tests, I am trying to Test user unlikes an article, using a pivot table (polymorphic relationship). This is the test:

    public function test_a_post_can_be_unliked()
    {
        // create a user
        $user = User::factory()->create();

        // this fakes a user login
        $this->actingAs($user);

        // create a topic based on the user id
        $topic = Topic::factory([
            'user_id' => $user->id,
        ])->create();

        // create an article based on the user id & topic id
        $article = Article::factory([
            'user_id' => $user->id,
            'topic_id' => $topic->id,
        ])->create();

        // this creates a like for the article based on the user id
        $article->like();

        // this checks if the article has 1 like
        $this->assertCount(1, $article->likes);

        // this checks if the user id is in the likes table
        $this->assertTrue($article->likes->contains('id', auth()->id()));

        // this unlikes the article
        $article->unlike();

        // this checks that there is no likes for the current user on the article
        $this->assertCount($article->likes->count() === 0, $article->likes);
    }

For some reason the last check is failing. I have removed RefreshDatabase to check what is happening & the $article->unlike() logic is all working fine. The like is actually removed from the database, so I don't understand why the last line is failing. I have also tried other code combinations to run this check and.they all fail. This is what I tried:

        $this->assertTrue($article->likes->doesntContain('id', auth()->id()));
		$this->assertFalse($article->likes->contains('id', auth()->id()));
        $this->assertEmpty($article->likes);

Please help me figure out what is going on here...

0 likes
2 replies
tykus's avatar
tykus
Best Answer
Level 104

First, assertCount takes an integer for the first argument whereas you are passing a Boolean.

Second, whenever you fetched the $article->likes Collection, here in the earlier assertion:

$this->assertCount(1, $article->likes);

that Collection becomes cached on the $article instance; it does not automagically update the likes Collection whenever you unlike the Article. You need to fetch them again for the subsequent count assertion (or just use the Builder)

$this->assertCount(0, $article->likes()->get());

// or using the Builder since you only need the count:
$this->assertEquals(0, $article->likes()->count());
CamKem's avatar
Level 10

@tykus Thanks for the detailed explanation, I appreciate it!

Please or to participate in this conversation.