Route model binding not working properly on feature test laravel 8

Viewed 35

While doing feature test against a patch endpoint, I'm getting new instance of eloquent instead of the desired eloquent model in the controller update method. Eloquent model generated in PurchaseTest.php is not passing to the PurchaseController.php through route model binding. But the route works properly when I use it via browser.

web.php
Route::name('admin.')->middleware(['admin'])->prefix('admin')->group(function () {
    Route::name('purchases.')->prefix('/purchases')->group(function () {
        Route::patch('/{purchase}/update', 'PurchaseController@update')->name('update');
    });
});
PurchaseTest.php
class PurchaseTest extends TestCase
{
    use RefreshDatabase;
    use WithoutMiddleware;

    public function test_purchase_can_be_updated()
    {
        $purchase = Purchase::create([
            "item" => "tariqs item",
            "support" => "2022-09-09",
            "status" => PurchaseStatus::ACTIVE,
            "purchase_code" => "1234",
            "username" => "tariq",
            "user_id" => "1",
        ]);
        
        // $purchase model is not passing to controller through this patch request.
        $response = $this->patch(route('admin.purchases.update', compact('purchase')), [
            "item" => "tariqs item edit",
            "support" => "2022-09-09",
            "status" => PurchaseStatus::ACTIVE,
            "purchase_code" => "1234",
            "username" => "tariq",
        ]);

        $response->assertStatus(200);
    }
}
PurchaseController.php
    public function update(Request $request, Purchase $purchase)
    {
        dd($purchase, $request->all());  // here $purchase is a new instance of $purchase, not the desired $purchase model.

        $input = $request->validate([
            "item" => "required|string",
            "support" => "required|date_format:Y-m-d",
            "status" => "required|string",
            "purchase_code" => "required|string",
            "username" => "required|string",
        ]);

        if ($purchase->update($input)) {
            $purchases = Purchase::where('user_id', $purchase->user_id)->get();
            return response()->json(['success' => 'true', 'msg' => __("Purchase code successfully updated."), 'embed' => view('admin.misc.purchase-list', compact('purchases'))->render()]);
        }

        throw ValidationException::withMessages(['error' => __('Something went wrong.')]);
    }
1 Answers

You probably need to do your route call like route('admin.purchases.update', $purchase) or route('admin.purchases.update', $purchase->id) without the compact()

Related