it-is-all-about-laravel's avatar

SQLite :memory: testing results inconsistent with MySql?

Hey Everyone, I've got an app with API resources where I've been using MySql for php unit tests. I attempted to move across to use sqlite :memory: as the testing having read about the potential speed/performance benefits.

After making the change I found a few examples of strange test results, where the API resource has started returning certain attributes values as blank, rather than than the value it should return.

More specifically the cases I've found of this problem seem to relate to where I've used eloquent Accessors to return the value. The strange aspect is that I use accessors on multiple fields, some return fine and others do not.

Any advice appreciated!

0 likes
2 replies
it-is-all-about-laravel's avatar

After further investigation I discovered the values returning blank were caused by sqlite returning integer column values as a string, rather than returning them as a numeric value. Eg sqlite returns the value "1" rather than 1, consequently the accessors I created returned null whenever it was called.

This behaviour of a string being returned for integers also causes some of my json testing to fail for fields where i don't use accessors. eg;

// my php unit test...

$attributes = [
    'project_id' = 1,
    'project_title' = 'My Test Project Title'
]

$user->projects()->update($attributes);

// test passes with mysql and sqlite
$this->assertDatabaseHas('matches', $attributes); 

// test fails with sqlite (but passes with mysql)
$this->json('GET', '/api/projects')
    ->assertJsonFragment($attributes);

error returned on failure is ;

Unable to find JSON fragment:

[{"project_id":1}]

in the sqlite json i find "project_id":"1" whereas in the mysql json i find "project_id": 1

i found this issues from 2014 which puts the cause due to pdo drivers. https://github.com/laravel/framework/issues/3548 . their suggested workaround is to explicitly cast the attributes to an integer in an accessor. this would solve it but seems very laborious to do field by field.

are there any other suggested options to solve this problem and be able to test json on sqlite without attribute specific accessors for all fields?

Please or to participate in this conversation.