realtebo's avatar

Laravel 8 - Testing a Package: record not found in db after queue has altered it

In my test, I post a fake image that is saved on a fake disk. This works

the tested controller save a record and dispatch a job

        Queue::assertPushed(UnpackUploadedFile::class, 1);

This test passes, I've a job dispatched

The job's handle() method alters the row just created, using update

        $this->batch_upload->update([
            'mime_type' => $mime,
            'status' => BatchUploadStatus::MIME_IDENTIFIED
        ]);

Then I dump (just for debugging ...) the record, and I can see

    [mime_type] => image/jpeg
    [status] => mime_identified

So I think that record has been altered in db.

Then my test [SAME TEST !] go on and tests db record

        $this->assertDatabaseHas(app(BatchUpload::class)->getTable(), [
            'original_file_name' => $fake_image->getClientOriginalName(),
            'disk_name' => $this->disk_name,
            'disk_path' => $fake_image->getClientOriginalName(),
            'status' => BatchUploadStatus::MIME_IDENTIFIED,
            'mime_type' => 'image/jpeg'
        ]);

I am getting this

Failed asserting that a row in the table [product_image_batch_uploads] matches the attributes {
    "original_file_name": "photo1.jpg",
    "disk_name": "product_image",
    "disk_path": "photo1.jpg",
    "status": "mime_identified",
    "mime_type": "image\/jpeg"
}.

Found similar results: [
    {
        "id": "1",
        "token": "a27afd8c-5c11-45e8-a0f7-36a8b56fced0",
        "original_file_name": "photo1.jpg",
        "disk_name": "product_image",
        "disk_path": "photo1.jpg",
        "mime_type": null,
        "status": "uploaded_locally",
        "created_at": "2020-12-01 10:28:23",
        "updated_at": "2020-12-01 10:28:23",
        "deleted_at": null
    }
].

So, in brief, job is dispatched, job does things and really alters the record, but when doing a lookup, the record looks like it has not been altered.

Note: I repeat: it's a single function, so db is not truncated and recreated in between the two actions

For testing I am using sqlite with :memory: as db

0 likes
3 replies
Sinnbeck's avatar

Could you post the full test, as well as how $this->batch_uploadis set ?

realtebo's avatar

Sure

    public function testUploadDispatchesJon()
    {
        $this->withoutExceptionHandling();

        Queue::fake();
        $fake_image = UploadedFile::fake()->image('photo1.jpg');

        $this->post(route('package.product-image.upload'), [
            'file' => $fake_image
        ]);

        Queue::assertPushed(UnpackUploadedFile::class, 1);

        $this->assertDatabaseHas(app(BatchUpload::class)->getTable(), [
            'original_file_name' => $fake_image->getClientOriginalName(),
            'disk_name' => $this->disk_name,
            'disk_path' => $fake_image->getClientOriginalName(),
            'status' => BatchUploadStatus::MIME_IDENTIFIED,
            'mime_type' => 'image/jpeg'
        ]);
    }

and, in the queue handle()

    public function handle()
    {
        /**
         * @var UploadedFile
         */
        $path = Storage::disk($this->batch_upload->disk_name)
                        ->path($this->batch_upload->disk_path);

        $mime = mime_content_type($path);
        $this->batch_upload->update([
            'mime_type' => $mime,
            'status' => BatchUploadStatus::MIME_IDENTIFIED
        ]);

        echo $path . "\n";
        echo $mime . "\n";
        print_r ($this->batch_upload->toArray());

    }

The output of this print_r is

Array
(
    [id] => 1
    [token] => b7730fa8-7675-40f4-a8de-ebd561d540c8
    [original_file_name] => photo1.jpg
    [disk_name] => product_image
    [disk_path] => photo1.jpg
    [mime_type] => image/jpeg
    [status] => mime_identified
    [created_at] => 2020-12-01T10:36:20.000000Z
    [updated_at] => 2020-12-01T10:36:20.000000Z
    [deleted_at] => 
)
realtebo's avatar

A coworker suggested I'm having the wrong approach. This test is for upload controller so I must end testing tyhat job is dispatched

Then I will create a new test file where i manually create record in the initial state, then I will call manually the job's handle() method so I can test results of single call from single predicatable state.

Please or to participate in this conversation.