kkhicher1's avatar

Test Single Pass but Fail when i test All

<?php

namespace Tests\Unit;

use App\Book;
use App\User;
use Tests\TestCase;
use App\Reservation;
use Exception;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;

class BookReservationTest extends TestCase
{
    use RefreshDatabase;
    /**
     * @test
     */
    public function a_book_can_be_checked_out()
    {
        // $book->checkout($user);
        $book = \factory(Book::class)->create();
        $user = \factory(User::class)->create();


        $book->checkout($user);

        $this->assertCount(1, Reservation::all());
        $this->assertEquals($user->id, Reservation::first()->user_id);
        $this->assertEquals($book->id, Reservation::first()->book_id);
        $this->assertEquals(now(), Reservation::first()->checked_out_at);
    }

    /**
     * @test
     */
    public function a_book_can_be_returned()
    {
        $book = \factory(Book::class)->create();
        $user = \factory(User::class)->create();

        $book->checkout($user);


        $book->checkin($user);

        $this->assertCount(1, Reservation::all());
        $this->assertEquals($user->id, Reservation::first()->user_id);
        $this->assertEquals($book->id, Reservation::first()->book_id);
        $this->assertEquals(now(), Reservation::first()->checked_in_at);
    }
    /**
     * @test
     */
    public function if_not_checked_out_exception_is_thrown()
    {
        $this->expectException(Exception::class);
        $book = \factory(Book::class)->create();
        $user = \factory(User::class)->create();

        $book->checkin($user);
    }
    /**
     * @test
     */
    public function a_book_can_check_out_a_book_twice()
    {
        $book = \factory(Book::class)->create();
        $user = \factory(User::class)->create();

        $book->checkout($user);
        $book->checkin($user);

        $book->checkout($user);


        $this->assertCount(2, Reservation::all());
        $this->assertEquals($user->id, Reservation::find(2)->user_id);
        $this->assertEquals($book->id, Reservation::find(2)->book_id);
        $this->assertNull(Reservation::find(2)->checked_in_at);
        $this->assertEquals(now(), Reservation::find(2)->checked_out_at);

        $book->checkin($user);

        $this->assertCount(2, Reservation::all());
        $this->assertEquals($user->id, Reservation::find(2)->user_id);
        $this->assertEquals($book->id, Reservation::find(2)->book_id);
        $this->assertNotNull(Reservation::find(2)->checked_in_at);
        $this->assertEquals(now(), Reservation::find(2)->checked_in_at);
    }
}

when i run test a_book_can_check_out_a_book_twice with filter it pass but when i run phpunit its fail and return error

1) Tests\Unit\BookReservationTest::a_book_can_check_out_a_book_twice
ErrorException: Trying to get property 'user_id' of non-object
0 likes
8 replies
mvd's avatar

Hi @kkhicher1 ,

Hard to see without any further code, but I think $this->assertEquals($user->id, Reservation::find(2)->user_id); your problem is here. What if you dump some code, what is the output?

$book = \factory(Book::class)->create();
        $user = \factory(User::class)->create();

        $book->checkout($user);
        $book->checkin($user);

        $book->checkout($user);

dump(Reservation::all());
dd(Reservation::find(2));

$this->assertCount(2, Reservation::all());
        $this->assertEquals($user->id, Reservation::find(2)->user_id);
        $this->assertEquals($book->id, Reservation::find(2)->book_id);
.....
drewdan's avatar

I wonder if its because data is persisting between tests? What does your PHPUnit config file look like?

kkhicher1's avatar

as i think..... when i run whole test total row will be 4. so in last method a_book_can_check_out_a_book_twice the Reservation::find(2) isn't exist because their may be id 3 and 4 exist ( when test all ) but on single test Reservation::find(2) return object that's why is success on single test? ? ? / ?

what you think?

mvd's avatar

@kkhicher1

what you think?

You can check this if you run the dumps from my previous post.

dd(Reservation::all());
drewdan's avatar

Could you show me your phpunit.xml file? I am intersted to see how you setup your test database?

kkhicher1's avatar
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
         bootstrap="vendor/autoload.php"
         colors="true">
    <testsuites>
        <testsuite name="Unit">
            <directory suffix="Test.php">./tests/Unit</directory>
        </testsuite>
        <testsuite name="Feature">
            <directory suffix="Test.php">./tests/Feature</directory>
        </testsuite>
    </testsuites>
    <filter>
        <whitelist processUncoveredFilesFromWhitelist="true">
            <directory suffix=".php">./app</directory>
        </whitelist>
    </filter>
    <php>
        <server name="APP_ENV" value="testing"/>
        <server name="BCRYPT_ROUNDS" value="4"/>
        <server name="CACHE_DRIVER" value="array"/>
        <server name="DB_CONNECTION" value="sqlite"/>
        <server name="DB_DATABASE" value=":memory:"/>
        <server name="MAIL_MAILER" value="array"/>
        <server name="QUEUE_CONNECTION" value="sync"/>
        <server name="DB_CONNECTION" value="mysql"/>
        <server name="DB_DATABASE" value="laravel7"/>
    </php>
</phpunit>

drewdan's avatar

Well first observation is:

<server name="DB_CONNECTION" value="sqlite"/>
<server name="DB_DATABASE" value=":memory:"/>
<server name="DB_CONNECTION" value="mysql"/>
<server name="DB_DATABASE" value="laravel7"/>

You set a memory db using sqlite, and then you overide it lines later using mysql. Is that intentional? Is the laravel7 database the same one you use for development? It could be some data persitting through your development process.

Please or to participate in this conversation.