在对补丁端点进行特性测试时,我在控制器更新方法中得到了新的雄辩模型实例,而不是所需的雄辩模型。PurchaseTest.php中生成的Eloquent模型没有通过路由模型绑定传递给PurchaseController.php。但当我通过浏览器使用该路线时,它可以正常工作。
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.')]);
}
我终于解决了这个问题!
验证在测试中是否使用了Trait WithoutMiddleware
如果是,请将其移除
就我而言,这就是问题所在!我在这里找到的。
在Laravel中,模型路由绑定是由一个middleware
完成的,所以当我使用这个Trait
时,我会删除所有的middlewares
。
您可能需要在没有compact()
的情况下执行类似route('admin.purchases.update', $purchase)
或route('admin.purchases.update', $purchase->id)
的路由调用
我遇到了同样的问题,我意识到要使模型绑定工作,我们需要在内核web或api中间件组中包含SubstituteBindings
中间件。因此,在任何情况下,如果您删除了它,您的模型绑定都将不起作用。
在我的案例中,我没有删除它,但我有一个中间件,我想在测试时跳过它,并使用withoutMiddleware()
方法来测试我的端点。它导致我的代码跳过所有的中间件。我通过指定我想要跳过的确切中间件来修复它,如下所示:
$this->withoutMiddleware([
AppHttpMiddlewareAuthenticate::class
])->...
当然,如果你使用Laravel的内置身份验证,你有更好的选择,比如:这里描述的$this->actingAs(...)
,但在我的情况下,它有点复杂。
希望它能帮助你。