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 模型与 ApplicantbelongsTo 关系,因此我需要先创建一个带有工厂的 Applicant 模型,然后再创建 ApplicationApplicant 也与 UserbelongsTo 关系,我也需要在之前创建...你明白了。

因此,简而言之,由于我要测试的一个模型的关系依赖性,我正在创建多个模型实例。

所以这让我想知道我是否采用了错误的方法?有没有更简单的方法,我只创建正在测试的模型?

这是我测试的代码:

/** 
 * @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
}