Laravel Test Not Validating Database Constraint -
i have laravel 5.3 app includes users
table. 1 of fields on table api_token
, in database definition set not null. if use postman , hit api endpoint creating user , don't include api_token
field, receive following error: sqlstate[hy000]: general error: 1364 field 'api_token' doesn't have default value
.
i haven't added code generate token yet, that's i'd expect. however, have phpunit test:
/** @test */ public function a_user_can_be_created() { $this->user_data = [ 'first_name' => 'jane', 'last_name' => 'smith', 'email_address' => 'jsmith@mailinator.com', 'phone' => '1234567890', 'username' => 'jsmith', 'password' => 'testing' ]; $this->post('/api/users', $this->user_data, array( 'accept' => 'application/json' )) ->assertresponsestatus(201) ->seejsonequals(['status' => 'success']) ->seeindatabase('users', $this->user_data); }
the problem test passes. how can test successful when database should throwing exception when user saved?
i've 'died , dumped' @ various points , confirmed data in fact being saved database when automated test runs. i've tried using same db both postman , automated test (instead of separate testing db) - same result.
i tried build minimal version of api , create similar test on latest laravel 5.3.22 version. used mariadb 10.1.13 database. , turns out test failed expected, because of empty api_token
.
1. users migration file
here's migration file creating users
table:
use illuminate\support\facades\schema; use illuminate\database\schema\blueprint; use illuminate\database\migrations\migration; class createuserstable extends migration { public function up() { schema::create('users', function (blueprint $table) { $table->increments('id'); $table->string('first_name'); $table->string('last_name'); $table->string('email_address')->unique(); $table->string('phone'); $table->string('username'); $table->string('password'); $table->string('api_token'); $table->timestamps(); }); } public function down() { schema::dropifexists('users'); } }
2. user model
here's app\user.php
file looks like. pretty minimal, update $fillable
property match our users
table structure:
namespace app; use illuminate\notifications\notifiable; use illuminate\foundation\auth\user authenticatable; class user extends authenticatable { use notifiable; protected $fillable = [ 'first_name', 'last_name', 'email_address', 'phone', 'username', 'password', 'api_token', ]; protected $hidden = [ 'password', ]; }
3. api routes file
i create new api route on routes/api.php
file create new user. super simple without validation involved:
route::post('users', function (request $request) { $data = $request->only([ 'first_name', 'last_name', 'email_address', 'phone', 'username', 'password', 'api_token', ]); if (is_string($data['password'])) { $data['password'] = bcrypt($data['password']); } $user = app\user::create($data); return response()->json([ 'status' => 'success', ], 201); });
4. create user api test
and here's test file testing our create user api.
class apitest extends testcase { /** @test */ public function a_user_can_be_created() { $user = [ 'first_name' => 'jane', 'last_name' => 'smith', 'email_address' => 'jsmith@mailinator.com', 'phone' => '1234567890', 'username' => 'jsmith', ]; $this->json('post', 'api/users', $user) ->assertresponsestatus(201) ->seejsonequals(['status' => 'success']) ->seeindatabase('users', array_except($user, ['password'])); } }
the difference used array_except()
exclude password
column database testing since hashed value before storing in database. of course not relate issue.
when run test without api_token
being set, test failed expected. api return status code of 500, while expected 201.
also reference, when set api_token
column not nullable, force create new user empty api_token
, exception message received this:
queryexception in connection.php line 769:
sqlstate[23000]: integrity constraint violation: 1048 column 'api_token' cannot null (sql: insert users...
hope debug issue!
Comments
Post a Comment