madphp
madphp

Reputation: 1764

Test not creating record, and truncating table

As I understand RefreshDatabase, it removes records created during test. The post in this feature test is not saving records, and actually truncating records created before test is ran.

The patient_details are encrypted/serialized in model. Posting from the front end, stores everything fine. But as soon as I run the test the table in truncated. I've tried reinstalling MySQL server, php artisan config:clear and cache:clear. I don't get any errors back and Patient::create seems to execute fine. I also tested this with sqlite database and get the same behavior.

Test

<?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('/');
    }

App\Patient

<?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);
            });
    }
}

Upvotes: 1

Views: 416

Answers (1)

Mohammad.Kaab
Mohammad.Kaab

Reputation: 1105

I think this trait RefreshDatabase basically runs the following method

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();
}

And as you can see the above method is calling migrate: fresh. and if you run migrate: fresh with --help you'll see what has been written in the description

Description: Drop all tables and re-run all migrations

So using RefreshDatabase trait basically will remove all of the tables and migrate them again. maybe you can use DatabaseTransactions for that purpose, it'll not remove the migrations I guess.

Upvotes: 1

Related Questions