使用Laravel 9更新和删除未通过测试的测试

ca1c2owp  于 2023-02-20  发布在  其他
关注(0)|答案(1)|浏览(94)

我已经创建了一个功能测试,以确保我的控制器按预期工作,但由于某种原因,测试不断失败,我得到此错误消息[路线:管理员/供应商/销毁] [URI:管理员/供应商/{供应商}] [缺少参数:供应商]。
我已将参数添加到路由中:route('admin/suppliers/destroy',$suppliers),但我仍然得到相同的错误,有人知道是什么可能导致此错误吗
这是我的测试

public function test_if_a_user_can_delete_a_supplier()
{
    //Make fake data, don't persist to database.
    $supplier = Supplier::factory()->make()->setAppends([])->makeHidden(['created_at', 'updated_at']);

    //Create an Admin User and assign the Administrator role to this new user
    $adminUser = factory(AdminUser::class)->create();
    $adminUser->roles()->sync(Role::where('name', 'Administrator')->first());

    $this->actingAs($adminUser, config('admin-auth.defaults.guard'))
        ->json(
            'DELETE',
            route('admin/suppliers/destroy', $supplier),
            $supplier->toArray()
        )
        ->assertStatus(302)
        ->assertRedirectToRoute('admin/suppliers/index');
    $this->assertDatabaseMissing(
        'suppliers',
        $supplier->toArray()

    );
}
jfewjypa

jfewjypa1#

//Make fake data, don't persist to database.
 $supplier = Supplier::factory()->make()->setAppends([])->makeHidden(['created_at', 'updated_at']);

您没有将Supplier模型持久化到数据库。
如果路由'admin/suppliers/destroy'的控制器方法中使用了路由模型绑定,那么route('admin/suppliers/destroy', $supplier)将返回HTTP 404 Not Found,这将导致测试失败,因为您期待的是HTTP 302 Found响应。
此外,当向路由传递变量时,它会尝试获取模型的id。由于您没有将$supplier持久化到数据库中,因此它没有id。
缺少[Route:admin/suppliers/destroy ] [URI:admin/suppliers/{supplier} ] [缺少参数:supplier ]。
即使没有$this->actingAs(...)语句,您的$this->assertDatabaseMissing(...)也会通过,因此您的测试实际上并没有测试它应该测试的内容。
我会这样改写测试:

public function test_if_an_admin_user_can_delete_a_supplier()
{
    // ARRANGE
    $supplier = Supplier::factory()->create(['name' => 'Fake Supplier']);
    $admin_role = Role::where('name', 'Administrator')->first();
    $admin_user = AdminUser::factory()->has($admin_role)->create();
    // Some people like to place a "pre-assertion" to make sure the Act phase is the reason changes occurred. In this case, it would look like this
    // $this->assertDatabaseHas('suppliers', ['name' => 'Fake Supplier']);

    // ACT
    $response = $this->actingAs($admin_user, config('admin-auth.defaults.guard'))
        ->deleteJson(route('admin/suppliers/destroy', $supplier), [
            'name' => 'Fake Supplier', /* using this or $supplier->name comes down to choice */
        ]);

    // ASSERT
    $response->assertStatus(302)
             ->assertRedirectToRoute('admin/suppliers/index');

    $this->assertDatabaseMissing('suppliers', [
        'name' => 'Fake Supplier', /* using this or $supplier->name comes down to choice */
    ]);
}

有些东西还是可以重构的。比如说,把这个

$admin_role = Role::where('name', 'Administrator')->first();
$admin_user = AdminUser::factory()->has($admin_role)->create();

使用工厂状态将它放到一行中,如果它是一行,在你的测试类中,重复出现的代码,那么将它作为setUp()方法的一个属性。

相关问题