Laravel 模型依赖多,测试前准备数据库,有没有更好的办法?
Laravel preparing the database before a test for a model with many dependencies, is there a better way?
我正在为我的网络应用程序和扩展 PHPUnit 的捆绑测试工具使用 Laravel 5.2。
我正在为对模型执行更新的页面编写测试。该测试检查模型的其中一个属性在提交表单之前是否未更改,以防止两个用户同时在浏览器中打开模型时更新模型。
测试需要在我的 Laravel 网络应用程序中使用一个模型,即 App\Models\Application
,我正在使用工厂为这个模型创建一些假数据。 Application
模型有许多 belongsTo
关系,这反过来要求在创建 Application
模型之前使用工厂在测试中创建相关模型。
例如,Application
模型与 Applicant
有 belongsTo
关系,因此我需要先创建一个带有工厂的 Applicant
模型,然后再创建 Application
和 Applicant
也与 User
有 belongsTo
关系,我也需要在之前创建...你明白了。
因此,简而言之,由于我要测试的一个模型的关系依赖性,我正在创建多个模型实例。
所以这让我想知道我是否采用了错误的方法?有没有更简单的方法,我只创建正在测试的模型?
这是我测试的代码:
/**
* @test
*/
public function throw_exception_when_application_status_is_modified_after_submission()
{
/**
* Arrange
*/
// create roles
factory(Role::class, 'admin')->create();
factory(Role::class, 'applicant')->create();
// create admin user
$adminUser = factory(User::class)->create();
$adminUser->attachRole(Role::whereName('admin')->first());
// create applicant user
$applicantUser = factory(User::class)->create();
$applicantUser->attachRole(Role::whereName('applicant')->first());
// create organisation with type
$organisationType = factory(OrganisationType::class)->create();
$organisation = factory(Organisation::class)->create();
$organisation->organisationTypes()->attach($organisation->id);
// create sub application
$subApplication = factory(ExperienceLetter::class)->create();
// create applicant
$applicant = factory(Applicant::class)->create([
'user_id' => $applicantUser->id
]);
// create application
$application = factory(Application::class)->make([
'status' => 'pending',
'application_id' => $subApplication->id,
'application_type' => 'App\Models\ExperienceLetter',
'organisation_id' => $organisation->id,
'applicant_id' => $applicant->id,
]);
// prep data
$data = [
'action' => 'accept',
'details' => 'email sent',
'application_id' => $application->id,
'application_status' => 'pending',
'verification' => 'email',
];
/**
* Act
*/
// log in
$this->actingAs($adminUser);
// alter status before call()
$application->status = 'verification';
$application->save();
$response = $this->call('POST', route('admin.application.action.store'), $data);
/**
* Assert
*/
$this->assertEquals(302, $response->status());
// assertSessionHasErrors
}
感谢任何建议。
您是否因为外键约束而创建所有这些?如果你只想检查一个没有任何关系的模型,那么 Schema::disableForeignKeyConstraints();
是你的朋友:
/**
* @test
*/
public function throw_exception_when_application_status_is_modified_after_submission()
{
\Schema::disableForeignKeyConstraints();
/**
* Arrange
*/
// create admin user
$adminUser = factory(User::class)->create();
$adminUser->attachRole(factory(Role::class, 'admin')->create());
// create application
$application = factory(Application::class)->make([
'status' => 'pending',
'application_id' => 0,
'application_type' => 'App\Models\ExperienceLetter',
'organisation_id' => 0,
'applicant_id' => 0,
]);
// prep data
$data = [
'action' => 'accept',
'details' => 'email sent',
'application_id' => $application->id,
'application_status' => 'pending',
'verification' => 'email',
];
/**
* Act
*/
// log in
$this->actingAs($adminUser);
// alter status before call()
$application->status = 'verification';
$application->save();
$response = $this->call('POST', route('admin.application.action.store'), $data);
\Schema::enableForeignKeyConstraints();
/**
* Assert
*/
$this->assertEquals(302, $response->status());
// assertSessionHasErrors
}
我正在为我的网络应用程序和扩展 PHPUnit 的捆绑测试工具使用 Laravel 5.2。
我正在为对模型执行更新的页面编写测试。该测试检查模型的其中一个属性在提交表单之前是否未更改,以防止两个用户同时在浏览器中打开模型时更新模型。
测试需要在我的 Laravel 网络应用程序中使用一个模型,即 App\Models\Application
,我正在使用工厂为这个模型创建一些假数据。 Application
模型有许多 belongsTo
关系,这反过来要求在创建 Application
模型之前使用工厂在测试中创建相关模型。
例如,Application
模型与 Applicant
有 belongsTo
关系,因此我需要先创建一个带有工厂的 Applicant
模型,然后再创建 Application
和 Applicant
也与 User
有 belongsTo
关系,我也需要在之前创建...你明白了。
因此,简而言之,由于我要测试的一个模型的关系依赖性,我正在创建多个模型实例。
所以这让我想知道我是否采用了错误的方法?有没有更简单的方法,我只创建正在测试的模型?
这是我测试的代码:
/**
* @test
*/
public function throw_exception_when_application_status_is_modified_after_submission()
{
/**
* Arrange
*/
// create roles
factory(Role::class, 'admin')->create();
factory(Role::class, 'applicant')->create();
// create admin user
$adminUser = factory(User::class)->create();
$adminUser->attachRole(Role::whereName('admin')->first());
// create applicant user
$applicantUser = factory(User::class)->create();
$applicantUser->attachRole(Role::whereName('applicant')->first());
// create organisation with type
$organisationType = factory(OrganisationType::class)->create();
$organisation = factory(Organisation::class)->create();
$organisation->organisationTypes()->attach($organisation->id);
// create sub application
$subApplication = factory(ExperienceLetter::class)->create();
// create applicant
$applicant = factory(Applicant::class)->create([
'user_id' => $applicantUser->id
]);
// create application
$application = factory(Application::class)->make([
'status' => 'pending',
'application_id' => $subApplication->id,
'application_type' => 'App\Models\ExperienceLetter',
'organisation_id' => $organisation->id,
'applicant_id' => $applicant->id,
]);
// prep data
$data = [
'action' => 'accept',
'details' => 'email sent',
'application_id' => $application->id,
'application_status' => 'pending',
'verification' => 'email',
];
/**
* Act
*/
// log in
$this->actingAs($adminUser);
// alter status before call()
$application->status = 'verification';
$application->save();
$response = $this->call('POST', route('admin.application.action.store'), $data);
/**
* Assert
*/
$this->assertEquals(302, $response->status());
// assertSessionHasErrors
}
感谢任何建议。
您是否因为外键约束而创建所有这些?如果你只想检查一个没有任何关系的模型,那么 Schema::disableForeignKeyConstraints();
是你的朋友:
/**
* @test
*/
public function throw_exception_when_application_status_is_modified_after_submission()
{
\Schema::disableForeignKeyConstraints();
/**
* Arrange
*/
// create admin user
$adminUser = factory(User::class)->create();
$adminUser->attachRole(factory(Role::class, 'admin')->create());
// create application
$application = factory(Application::class)->make([
'status' => 'pending',
'application_id' => 0,
'application_type' => 'App\Models\ExperienceLetter',
'organisation_id' => 0,
'applicant_id' => 0,
]);
// prep data
$data = [
'action' => 'accept',
'details' => 'email sent',
'application_id' => $application->id,
'application_status' => 'pending',
'verification' => 'email',
];
/**
* Act
*/
// log in
$this->actingAs($adminUser);
// alter status before call()
$application->status = 'verification';
$application->save();
$response = $this->call('POST', route('admin.application.action.store'), $data);
\Schema::enableForeignKeyConstraints();
/**
* Assert
*/
$this->assertEquals(302, $response->status());
// assertSessionHasErrors
}