Summer Sale! All accounts are 50% off this week.

alnouirah's avatar

unsignedInteger exccept stirng without throwing an error !

Hy folks , at first, I was having that test :

 $this->admin->update([
            'first_name'    => 'updated-first_name',
            'status'    => 'approved'
        ]);

$this->assertEquals($this->admin->refresh()->getAttributes()->toArray(),[
            'first_name'    => 'updated-first_name',
            'status'    => 'approved',
        ])

at this point, everything is going right. but after I decide to change the status to be an integer I have changed the migration like the following :

$table->unsignedInteger('status')->default(0);

I was expecting that the test will fail but it's still passed !! to make sure I die and dumped the user after the updated process and I got its status updated to string !!! it should throw a database exception or I am missing something here !!

0 likes
7 replies
Nakov's avatar

You have changed an existing migration or you added a new one? Which trait are you using in your tests for the Database?

Do you maybe cast or have a mutator in your Admin model for the status field?

1 like
alnouirah's avatar

@Nakov First of all Thanks a lot for your response :). "You have changed an existing migration or you added a new one?" I have only one migration for the users table. "Which trait are you using in your tests for the Database?" Laravel test case :

use Tests\TestCase;

class UserManagementTest extends TestCase
{
    use RefreshDatabase;
}

"Do you maybe cast or have a mutator in your Admin model for the status field?" I was having some constants that referred to the status but the problem is not here! The problem is why unsignedInteger column can accept a string as a value! it should throw a database invalid argument right !!

Nakov's avatar

@alnouirah yes it should, that probaby means that the migration didn't run if you still can store string value. Or it casts the string to an integer before ot gets stored.

alnouirah's avatar

To make sure that I am in the right way I have to add the following line to know what the exact type of the column :

dd(DB::connection()->getDoctrineColumn('users', 'status')->getType()->getName());

It prints integer !! so what makes an integer column to accept a string value! BYT. I am using SQLite and a :memory: database inside PHPUnit XML configuration file.

Nakov's avatar

@alnouirah What of you DD this

$this->admin->refresh()->getAttributes()->toArray()
1 like
alnouirah's avatar

@Nakov I figured it out. it just sqlit dynamic feature. I am using sqlit database in memory. Thanks in advance for your help :) .

alnouirah's avatar
alnouirah
OP
Best Answer
Level 2

Oh got it.

This is a frequently asked question—it's literally in SQLite's FAQ: (3) SQLite lets me insert a string into a database column of type integer! This is a feature, not a bug. SQLite uses dynamic typing. It does not enforce data type constraints. Any data >can be inserted into any column. You can put arbitrary length strings into integer columns, floating point >numbers in boolean columns, or dates in character columns. The datatype you assign to a column in the >CREATE TABLE command does not restrict what data can be put into that column. Every column is able to hold >an arbitrary length string. (There is one exception: Columns of type INTEGER PRIMARY KEY may only hold a 64->bit signed integer. An error will result if you try to put anything other than an integer into an INTEGER PRIMARY >KEY column.)

But SQLite does use the declared type of a column as a hint that you prefer values in that format. So, for >example, if a column is of type INTEGER and you try to insert a string into that column, SQLite will attempt to >convert the string into an integer. If it can, it inserts the integer instead. If not, it inserts the string. This feature is >called type affinity. It was sqlit feature not a laravel or sqlit bug . https://stackoverflow.com/questions/10772028/boolean-datatype-accepting-string-value-and-integer-value

Please or to participate in this conversation.