Making http test in laravel 8 in control I create $itemObject object with factory and pass it for edit method
use Tests\TestCase;
class ControllersItemObjectController extends TestCase
{
use DatabaseMigrations;
/** @test */
public function edit_item_object()
{
$this->withoutMiddleware();
$itemObject = ItemObject::factory()->create();
\Log::info(json_encode($itemObject); // I see valid object logged
\Log::info(gettype($itemObject)); // it shows "object"
$this->asAdmin()->get(route('item-objects.edit', ['item_object' => $itemObject]));
and I got error :
Missing required parameter for [Route: item-objects.update] [URI: item-objects/{item_object}] [Missing parameter: item_object]. (View:
/resources/views/item-objects/edit.blade.php)
in routes I have :
| | GET|HEAD | item-objects/{item_object}/edit | item-objects.edit | App\Http\Controllers\ItemObjectController@edit | web |
But in ItemObjectController controller I have :
public function edit(ItemObject $itemObject)
{
\Log::info( json_encode($itemObject) ); // but it returns empty array
return view('item-objects.edit', [
...
]);
}
As parameter $itemObject above is empty it raise error in /resources/views/item-objects/edit.blade.php template above. But I do not see why this parameter is empty ? Where I lose this value passing valid object into ItemObjectController.edit method?
If there is a way to debug it ? I can not use TELESCOPE for tests...
In route parameter is "item_object", but var name is "$itemObject" I do not see wht $itemObject is empty ...
Thanks in advance!
CodePudding user response:
First of all, the error is being shown for item-objects.update
, but the route you have shared is for item-objects.edit
.
So, you have also shared the controller for edit
, and you are using item_object
in the route but using $itemObject
in your controller... When you want to use Implicit Model Binding you have to match the parameter with the variable name, so you either use itemObject
or item_object
(I would recommend the first one):
public function edit(ItemObject $itemObject)
{
return view('item-objects.edit', [
...
]);
}
Route::get(`item-objects/{itemObject}/edit`, [\App\Http\Controllers\ItemObjectController::class, 'edit'])
->name('item-objects.edit);
After that is done, your test should also match the route:
public function edit_item_object()
{
$this->withoutMiddleware();
$itemObject = ItemObject::factory()->create();
$this->asAdmin()
->get(route('item-objects.edit', ['item_object' => $itemObject]));
CodePudding user response:
In this case you dont need to encode to json. You need to pass the attribute which is used for model bindings in your routes file.
as an example, you can have something like this:
Route::bind('item_object', fn (string $value) => ItemObject::query()->findOrFail($value));
The code above, responsible for mapping route param with model from DB. But in your case it might be different. I do prefer to follow explicit model bindings,instead of magic :)