mardi 26 janvier 2021

Laravel Testing: Getting "Call to a member function bound() on null" at Illuminate\Routing\Route after successful response

I am building a test in my Laravel application to check order fulfillment by deleting an order, recreating it and then attempting to fulfill it. I've included the test below having commented out the parts that I've isolated as unrelated, and all it's doing is a putJson() which returns a successful response ($responseMakeOrderReadyToPick) with no exceptions thrown.

class LegacyOrderFulfillmentTest extends TestCase
{
    // Declare the legacy order id of the legacy order to seed.
    const LEGACY_ORDER_ID = ***;

    /**
     * @return void
     * @throws AuthorizationException
     * @throws NoResultException
     * @throws RetryableException
     */
    public function test_super_admin_can_add_and_fulfill_legacy_order()
    {
        // Sign in as the super admin.
        $this->beSuperAdmin();

        // Delete the current legacy order.
//      /** @var LegacyOrderMigrationManager $migrationManager */
//      $migrationManager = resolve(LegacyOrderMigrationManager::class);
//
//      $migrationManager->deleteCustomerOrderFromLegacyId(self::LEGACY_ORDER_ID);
//
//      // Re-seed the legacy order.
//      Artisan::call('dshell:seed:legacy:orders', [
//          '--id' => self::LEGACY_ORDER_ID,
//      ]);

        /**
         * Load the newly created legacy order.
         *
         * @var CustomerOrder $order
         */
        $order = Repo::make(CustomerOrder::class)->findLast();

        // Make the order ready to pick.
        $responseMakeOrderReadyToPick = $this->putJson(route('admin::customer-orders.verifyShippingAddress', [$order->getPublicId()]));

        $responseMakeOrderReadyToPick->assertSuccessful();

//      $this-refreshApplication();
//      $this->beSuperAdmin();

        /**
         * Declare the smart scanner.
         *
         * @var SmartScanner $scanner
         */
        $scanner = Repo::make(SmartScanner::class)->find('L9IM5BcHztTbFLI05lV');

        $scannerDeviceId = $scanner->getDeviceId();

        // Define the device id.
        $_COOKIE[Utils::GetSmartInterfaceDeviceIdCookieName()] = $scannerDeviceId;

        // Create a new pick list.
        $responseCreateNewPickList = $this->postJson(route('admin::smart-scanner-interface.index'), [
            'sidId' => $scannerDeviceId,
            'programName' => SmartDeviceInterfaceController::PROGRAM_PICK,
            'parameters' => json_encode($this->getSmartDeviceParameters()),
            'pickListDefined' => 0,
            'pickTask' => '',
        ], ['HTTP_X-Requested-With' => 'XMLHttpRequest']);

        dd($responseCreateNewPickList->exception);

        $responseCreateNewPickList->assertSuccessful();
    }

    private function getSmartDeviceParameters(): array
    {
        /** @var Location $mobileLocation */
        $mobileLocation = Repo::make(Location::class)->find('HzDTxwsSaSEOwZg3T8k');

        /** @var PickStrategy $pickStrategy */
        $pickStrategy = Repo::make(PickStrategy::class)->find('G1lu1aW135i9bvZltpq');

        return [
            'mobileLocation' => [
                'name' => 'mobileLocation',
                'value' => $mobileLocation->getPublicId(),
            ],
            'pickStrategy' => [
                'name' => 'pickStrategy',
                'value' => $pickStrategy->getPublicId(),
            ],
            'carrier' => [
                'name' => 'carrier',
                'value' => '',
            ],
            'order' => [
                'name' => 'order',
                'value' => '',
            ],
            'expeditedOnly' => [
                'name' => 'expeditedOnly',
                'value' => '',
            ],
            'cutoffOverride' => [
                'name' => 'cutoffOverride',
                'value' => '',
            ],
        ];
    }
}

But for some reason this causes the second response ($responseCreateNewPickList) to fail with the below stack trace.

PHPUnit\Framework\Exception: Symfony\Component\Debug\Exception\FatalThrowableError {#6143
  #message: "Call to a member function bound() on null"
  #code: 0
  #file: "C:\Zaad\code\repositories\namaan\dshell\vendor\laravel\framework\src\Illuminate\Routing\Route.php"
  #line: 807
  #severity: E_ERROR
  trace: {
    C:\Zaad\code\repositories\namaan\dshell\vendor\laravel\framework\src\Illuminate\Routing\Route.php:807 { …}
    C:\Zaad\code\repositories\namaan\dshell\vendor\laravel\framework\src\Illuminate\Routing\Route.php:795 { …}
    C:\Zaad\code\repositories\namaan\dshell\vendor\laravel\framework\src\Illuminate\Routing\Route.php:757 { …}
    C:\Zaad\code\repositories\namaan\dshell\vendor\laravel\framework\src\Illuminate\Routing\Router.php:671 { …}
    C:\Zaad\code\repositories\namaan\dshell\vendor\laravel\framework\src\Illuminate\Routing\Router.php:651 { …}
    C:\Zaad\code\repositories\namaan\dshell\vendor\laravel\framework\src\Illuminate\Routing\Router.php:635 { …}
    C:\Zaad\code\repositories\namaan\dshell\vendor\laravel\framework\src\Illuminate\Routing\Router.php:601 { …}
    C:\Zaad\code\repositories\namaan\dshell\vendor\laravel\framework\src\Illuminate\Routing\Router.php:590 { …}
    C:\Zaad\code\repositories\namaan\dshell\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php:176 { …}
    C:\Zaad\code\repositories\namaan\dshell\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:30 { …}
    C:\Zaad\code\repositories\namaan\dshell\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode.php:46 { …}
    C:\Zaad\code\repositories\namaan\dshell\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:149 { …}
    C:\Zaad\code\repositories\namaan\dshell\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:53 { …}
    C:\Zaad\code\repositories\namaan\dshell\vendor\itsgoingd\clockwork\Clockwork\Support\Laravel\ClockworkMiddleware.php:28 { …}
    C:\Zaad\code\repositories\namaan\dshell\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:149 { …}
    C:\Zaad\code\repositories\namaan\dshell\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:53 { …}
    C:\Zaad\code\repositories\namaan\dshell\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:102 { …}
    C:\Zaad\code\repositories\namaan\dshell\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php:151 { …}
    C:\Zaad\code\repositories\namaan\dshell\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php:116 { …}
    C:\Zaad\code\repositories\namaan\dshell\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\MakesHttpRequests.php:345 { …}
    C:\Zaad\code\repositories\namaan\dshell\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\MakesHttpRequests.php:317 { …}
    C:\Zaad\code\repositories\namaan\dshell\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\MakesHttpRequests.php:208 { …}
    C:\Zaad\code\repositories\namaan\dshell\tests\Feature\LegacyOrderFulfillmentTest.php:81 {
      › \t'pickTask' => '',\r
      › ], ['HTTP_X-Requested-With' => 'XMLHttpRequest']);\r
      › \r
      arguments: {
        $uri: "https://localhost/admin/smart-scanner-interface"
        $data: array:5 [ …5]
        $headers: array:1 [ …1]
      }
    }
    Tests\Feature\LegacyOrderFulfillmentTest->test_super_admin_can_add_and_fulfill_legacy_order() {}
    C:\Zaad\code\repositories\namaan\dshell\vendor\phpunit\phpunit\src\Framework\TestCase.php:1071 { …}
    C:\Zaad\code\repositories\namaan\dshell\vendor\phpunit\phpunit\src\Framework\TestCase.php:939 { …}
    C:\Zaad\code\repositories\namaan\dshell\vendor\phpunit\phpunit\src\Framework\TestResult.php:698 { …}
    C:\Zaad\code\repositories\namaan\dshell\vendor\phpunit\phpunit\src\Framework\TestCase.php:894 { …}
    C:\Users\Namaan\AppData\Local\Temp\PHPCFB2.tmp:263 { …}
    C:\Users\Namaan\AppData\Local\Temp\PHPCFB2.tmp:552 { …}
  }
}

But if I uncomment "$this-refreshApplication()" and "$this->beSuperAdmin()", it prevents the above exception from being thrown, though it creates some other issue involving what seems to be an infinite loop in my application logic involving jobs being dispatched synchronously due to the testing environment. Before I try and debug that, I want to try and make sense of this first, as it doesn't seem like I should be having to call refreshApplication() between requests, particularly when the first request succeeds.

The strange thing is, if I comment out the first request (responseMakeOrderReadyToPick), while keeping "$this-refreshApplication()" and "$this->beSuperAdmin()" commented, then the second request works as expected, and returns the expected response. So something about the first request is effecting the second one.

Hoping someone can help!

Aucun commentaire:

Enregistrer un commentaire