Laravel Unit Testing, how is the "seeInDatabase" soft-deleted row?

I am working on a small unit test, where I gently delete the line. To mark the test as successful, I have to find this line with:

  • given identifier and
  • deleted_at column must not be null.

I can fulfill the first condition - because, obviously, I know the ID.

Unfortunately, I don’t know how to say the seeInDatabase method, which I expect deleted_at not be null:

 $this->seeInDatabase( 'diary_note_categories', [ 'id' => 'a7e35ad0-6f00-4f88-b953-f498797042fc', 'deleted_at' => null // should be is not null, like <> or != or whatever ] ); 

Any clues?

'deleted_at <>' => null breaks

'deleted_at' => ['!=' => null] also breaks

+9
php unit-testing testing laravel laravel-5
source share
4 answers

This is currently not possible. Both seeInDatabase and notSeeInDatabase just pass the array directly to the where method of the query designer and don’t understand how to handle anything except = when passing the array.

https://github.com/laravel/framework/blob/2b4b3e3084d3c467f8dfaf7ce5a6dc466068b47d/src/Illuminate/Database/Query/Builder.php#L452

 public function where($column, $operator = null, $value = null, $boolean = 'and') { // If the column is an array, we will assume it is an array of key-value pairs // and can add them each as a where clause. We will maintain the boolean we // received when the method was called and pass it into the nested where. if (is_array($column)) { return $this->whereNested(function ($query) use ($column) { foreach ($column as $key => $value) { $query->where($key, '=', $value); } }, $boolean); } // ... } 

Option 1 - add the following code to your TestCase class, which you extend your test cases from

Gist: https://gist.github.com/EspadaV8/73c9b311eee96b8e8a03

 <?php /** * Assert that a given where condition does not matches a soft deleted record * * @param string $table * @param array $data * @param string $connection * @return $this */ protected function seeIsNotSoftDeletedInDatabase($table, array $data, $connection = null) { $database = $this->app->make('db'); $connection = $connection ?: $database->getDefaultConnection(); $count = $database->connection($connection) ->table($table) ->where($data) ->whereNull('deleted_at') ->count(); $this->assertGreaterThan(0, $count, sprintf( 'Found unexpected records in database table [%s] that matched attributes [%s].', $table, json_encode($data) )); return $this; } /** * Assert that a given where condition matches a soft deleted record * * @param string $table * @param array $data * @param string $connection * @return $this */ protected function seeIsSoftDeletedInDatabase($table, array $data, $connection = null) { $database = $this->app->make('db'); $connection = $connection ?: $database->getDefaultConnection(); $count = $database->connection($connection) ->table($table) ->where($data) ->whereNotNull('deleted_at') ->count(); $this->assertGreaterThan(0, $count, sprintf( 'Found unexpected records in database table [%s] that matched attributes [%s].', $table, json_encode($data) )); return $this; } 

Option 2 - Install the next composer kit

This composite package is the same code as above, but packaged for Composer.

composer require kirkbater/soft-deletes

Then use it inside your specific test class:

 <?php use Kirkbater\Testing\SoftDeletes; class MyTestClass extends TestClass { use SoftDeletes; } 
+13
source share

I did it as follows:

 $this->seeInDatabase('diary_note...',['id' => 'a7e35ad0']) ->notSeeInDatabase('diary_note...',['id' => 'a7e35ad0','deleted_at'=>null]); 

So, I check two steps.

  • I check if there is an entry with our identifier in the table
  • I check if there is a record in our id and deleted_at = null in the table
+29
source share

This is an old question, but for those using more recent versions of Laravel (5.4 and above), there is now assertSoftDeleted : documentation .

Thus, the answer to the original question will now be:

 $this->assertSoftDeleted('diary_note_categories', [ 'id' => 'a7e35ad0-6f00-4f88-b953-f498797042fc' ]); 
+8
source share

It is not tested, but try like this:

 $this->seeInDatabase( 'diary_note_categories', [ 'id' => 'a7e35ad0-6f00-4f88-b953-f498797042fc', 'deleted_at' => ['deleted_at' ,'!=', null ] // should be is not null, like <> or != or whatever ] ); 
-2
source share

All Articles