Annaro's avatar

Test OK alone but ERROR in test suite + Attempt to read property on null

I am using Laravel 8, PHPUnit 9.5.4. I have a test that is marked as OK when i run it alone, but it gives me an error if i run the whole suite:

$ ./vendor/bin/phpunit --filter daily_credits_are_initialised_depending_on_the_package
PHPUnit 9.5.4 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 00:12.466, Memory: 30.00 MB

OK (1 test, 36 assertions)

Now when i run the whole suite, it gives an error:

$ ./vendor/bin/phpunit
PHPUnit 9.5.4 by Sebastian Bergmann and contributors.

.....................................E                            38 / 38 (100%)

Time: 00:26.160, Memory: 44.50 MB

There was 1 error:

1) Tests\Feature\CustomerPackageTest::daily_credits_are_initialised_depending_on_the_package
ErrorException: Attempt to read property "package_daily_credit" on null

/Users/adrien/Documents/laravel/A_REAL_PROJECT/app/Http/Controllers/CustomerPackageController.php:76
/Users/adrien/Documents/laravel/A_REAL_PROJECT/app/Http/Controllers/CustomerPackageController.php:53
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Routing/Controller.php:54
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php:45
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Routing/Route.php:254
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Routing/Route.php:197
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Routing/Router.php:695
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:128
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php:50
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php:44
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php:78
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php:49
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php:121
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php:64
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php:37
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php:67
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:103
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Routing/Router.php:697
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Routing/Router.php:672
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Routing/Router.php:636
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Routing/Router.php:625
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:166
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:128
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php:21
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php:31
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php:21
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php:40
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php:27
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php:86
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/fruitcake/laravel-cors/src/HandleCors.php:38
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/fideloper/proxy/src/TrustProxies.php:57
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:103
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:141
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:110
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php:509
/Users/adrien/Documents/laravel/A_REAL_PROJECT/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php:321
/Users/adrien/Documents/laravel/A_REAL_PROJECT/tests/Feature/SubscriptionTest.php:62

ERRORS!
Tests: 38, Assertions: 102, Errors: 1.

How is THAT possible?

Here is the code of the test that passes alone and gives an error in the suite:

<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
use App\Models\User;
use App\Models\CustomerPackage;
use App\Models\PackageDailyCredit;
use App\Models\PackageToolboxSize;
use App\Models\Package;
use App\Models\DailyCredit;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
use Carbon\CarbonPeriod;

class CustomerPackageTest extends TestCase
{
    use RefreshDatabase;

    /** @test */
    public function daily_credits_are_initialised_depending_on_the_package()
    {
        $this->withoutExceptionHandling();

        $this->registerNewUser(); 
        $this->createPackageWithFreeTrial(); 

        $response = $this->post(route('customer_package.free_trial', [
            'package_id' => 1
        ]));

        $date_from = Carbon::today();        
        $date_to = Carbon::today()->addMonths(1);
        $number_days_customer_package = $date_to->diffInDays($date_from) + 1;
        
        $this->assertCount($number_days_customer_package, DailyCredit::all());

        $customer_package_period = CarbonPeriod::create($date_from, $date_to);

        $dates = [];
        foreach($customer_package_period as $date) {

            $this->assertDatabaseHas('daily_credits', [
                'user_id' => auth()->user()->id,
                'date' => $date->format('Y-m-d'),
                'number_daily_credits' => CustomerPackage::first()->package->package_daily_credit->number_daily_credits,
                'number_credits_left' => CustomerPackage::first()->package->package_daily_credit->number_daily_credits
            ]);
        }
    }


    protected function registerNewUser()
    {
        return $this->post('/register', [
            'name' => 'Jo Sim',
            'toolbox' => 'josim',
            'email' => '[email protected]',
            'password' => 'josimjosim',
            'password_confirmation' => 'josimjosim',
        ]); 
    }


    protected function createPackageWithFreeTrial()
    {
        DB::table('package_daily_credits')->insert([
            'title' => 'Basic',
            'number_daily_credits' => 5
        ]);
        $this->assertCount(1, PackageDailyCredit::all());

        DB::table('package_toolbox_sizes')->insert([
            'title' => 'Little Toolbox',
            'max_swaps_per_credit' => 50,
        ]);
        $this->assertCount(1, PackageToolboxSize::all());

        DB::table('packages')->insert([
            'package_daily_credit_id' => 1,
            'package_toolbox_size_id' => 1,
            'description' => 'description text',
            'price_in_CA' => 10,
            'free_trial' => true,
        ]);
        $this->assertCount(1, Package::all());
    }
}

Here is the function called from CustomerPackageController.php:

    public function free_trial()
    {
        $data = request()->validate([
            'package_id'=>'required',
        ]); 

        $package_id = request('package_id');
        $date_from = Carbon::today();       
        $date_to = Carbon::today()->addMonths(1);

        $customer_package = CustomerPackage::create([
            'package_id' => $package_id,
            'user_id' => auth()->user()->id,
            'date_from' => $date_from,        
            'date_to' => $date_to
        ]);

        $dateRange = CarbonPeriod::create($date_from, $date_to);

        $dates = [];
        foreach($dateRange as $date) {
            $daily_credits = DailyCredit::create(
                [
                    'user_id' => auth()->user()->id,
                    'date' => $date->format('Y-m-d'),
                    'number_daily_credits' => $customer_package->package->package_daily_credit->number_daily_credits,
                    'number_credits_left' => $customer_package->package->package_daily_credit->number_daily_credits,
                ]
            ); 
        }

        $message_package = ($date_from == Carbon::today()) ? 
                            "Your plan is valid starting today." : 
                            "Your new plan will be valid from";
       $message = "Go to the <a class='underline uppercase' href='dashboard'>dashboard</a> to start using the service.<br>".$message_package;

        return redirect(route('account.index'))->with('message_package_added', $message)->with('date_from', $date_from)->with('date_to', $date_to); 
    }

However, if i

dd(CustomerPackage::first()->package->package_daily_credit->number_daily_credits);

before my foreach loop in CustomerPackageController, i get this when i run the test suite:

./vendor/bin/phpunit
PHPUnit 9.5.4 by Sebastian Bergmann and contributors.

....................................5

Which kinda proves again that the error is not valid... Please let me know what i am missing.

Help please! :) Thank you!!

0 likes
2 replies
kevinbui's avatar

This is super weird. But it happens to me from time to time too :).

Have you tried dumping the value inside the loop?

Have you tried refresh the $customer_package object before the loop?

$customer_package->refresh();

You might also want to try restarting your dev environment and clear the testing cache, if there's any.

Annaro's avatar
Annaro
OP
Best Answer
Level 2

Id's do not start at 1 in this test if i launch the test suite. Everything works when i use Package::first()->id instead of 1 (and same for other ids).

Please or to participate in this conversation.