【问题标题】:Test not creating record, and truncating table测试不创建记录和截断表
【发布时间】:2019-11-25 05:32:24
【问题描述】:

据我了解 RefreshDatabase,它会删除在测试期间创建的记录。此功能测试中的帖子不保存记录,实际上是截断运行测试之前创建的记录。

patient_details 在模型中被加密/序列化。从前端发布,存储一切正常。但是,一旦我运行测试,表格就会被截断。我试过重新安装 MySQL 服务器,php artisan config:clear 和 cache:clear。我没有收到任何错误,而且 Patient::create 似乎执行得很好。我还使用 sqlite 数据库对此进行了测试,并获得了相同的行为。

测试

<?php

namespace Tests\Feature;

use App\Patient;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\withoutExceptionHandling;
use Illuminate\Support\Facades\Crypt;
use Tests\TestCase;

class PatientTest extends TestCase
{

    use RefreshDatabase;

    /** @test */
    public function patient_details_are_posted_encrypted_and_saved()
    {


        $this->withoutExceptionHandling();

        $newPatient = factory('App\Patient')->make();

        $response = $this->post('/patient', $newPatient->patient_details);

        $patients = new Patient;
        $patients->all();
        $patient = $patients->last();

        $this->assertEquals($newPatient->patient_details, Crypt::decrypt($patient->patient_details));

    }

}

Controller@store

/**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {

        $attributes = request()->validate([
            'prefix' => 'nullable',
            'first_name' => 'required',
            'middle_name' => 'nullable',
            'last_name' => 'required',
            'suffix' => 'nullable',
            'sex' => 'nullable',
            'street_address' => 'required',
            'city' => 'required',
            'state' => 'required',
            'zip' => 'required',
            'home_phone' => 'nullable',
            'work_phone' => 'nullable',
            'cell_phone' => 'nullable',
            'email' => 'required',
            'dob' => 'nullable|date'
        ]);

        Patient::create(['patient_details' => $attributes]);

        return redirect('/');
    }

应用\患者

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Crypt;

class Patient extends Model
{
    protected $guarded = [];

    public static function boot()
    {
            parent::boot();

            self::creating(function($model){
                $model->patient_details = Crypt::encrypt($model->patient_details);
            });
    }
}

【问题讨论】:

  • “据我了解,RefreshDatabase 会删除测试期间创建的记录。”不,正如答案中提到的,它清除了整个事情。这在文档中没有得到很好的解释,我也有同样的困惑。我建议使用.env.testing 文件指向与生产数据库不同的数据库。

标签: laravel laravel-5.8


【解决方案1】:

我认为这个 trait RefreshDatabase 基本上运行以下方法

protected function refreshTestDatabase()
{
    if (! RefreshDatabaseState::$migrated) {
        $this->artisan('migrate:fresh', [
            '--drop-views' => $this->shouldDropViews(),
            '--drop-types' => $this->shouldDropTypes(),
        ]);

        $this->app[Kernel::class]->setArtisan(null);

        RefreshDatabaseState::$migrated = true;
    }

    $this->beginDatabaseTransaction();
}

如您所见,上述方法调用了 migrate:fresh。如果你运行 migrate: fresh 和 --help 你会看到描述中写了什么

说明: 删除所有表并重新运行所有迁移

因此,使用 RefreshDatabase 特征基本上会删除所有表并再次迁移它们。也许您可以为此目的使用 DatabaseTransactions,它不会删除我猜的迁移。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-31
    • 2015-10-18
    • 1970-01-01
    • 2019-02-02
    • 1970-01-01
    • 2021-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多