Laravel Unit Testing,如何"seeInDatabase"软删除行?

Mat*_*cki 9 php testing unit-testing laravel laravel-5

我正在进行小型单元测试,我在其中软删除一行.要将测试标记为成功,我必须找到以下行:

  • 给定的ID和
  • deleted_at不应为 null.

我可以满足第一个条件 - 因为显然我知道ID.

不幸的是我不知道如何告诉seeInDatabase我希望deleted_at 不为 null的方法:

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

任何提示?

'deleted_at <>' => null 休息

'deleted_at' => ['!=' => null] 也打破了

小智 33

我是这样做的:

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

所以我分两步检查

  1. 我检查表中是否有我们的id记录
  2. 我检查表中是否没有带有id和deleted_at = null的记录


小智 13

目前还不可能.双方seeInDatabasenotSeeInDatabase只需直接将数组传递给where查询生成器的方法,并且不知道如何处理以外的任何=时候通过一个数组.

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);
    }

    // ...
}
Run Code Online (Sandbox Code Playgroud)

选项1 - 将以下代码添加到您扩展测试用例的TestCase类中

要点: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;
}
Run Code Online (Sandbox Code Playgroud)

选项2 - 安装以下composer包

这个composer包与上面的代码完全相同,但是为Composer打包.

composer require kirkbater/soft-deletes

然后在特定测试类中使用它:

<?php

use Kirkbater\Testing\SoftDeletes;

class MyTestClass extends TestClass {

    use SoftDeletes;

}
Run Code Online (Sandbox Code Playgroud)


Glu*_*ear 8

这是一个老问题,但对于那些使用更新版本的Laravel(5.4及更高版本)的人来说,现在有一个assertSoftDeleted断言:文档.

所以现在问题的答案是:

$this->assertSoftDeleted('diary_note_categories', [
    'id' => 'a7e35ad0-6f00-4f88-b953-f498797042fc'
]);
Run Code Online (Sandbox Code Playgroud)


Bog*_*huk 6

断言给定的记录已被删除(Laravel 5.4 及更高版本)。

assertSoftDeleted (字符串|模型$table, 数组$data = [], 字符串|null $connection = null)

带有 id 的示例:

$this->assertSoftDeleted('table_name', ['id'='value'])
Run Code Online (Sandbox Code Playgroud)

模型示例:

$user = User::factory()->create();
$user->delete();
$this->assertSoftDeleted($user);
Run Code Online (Sandbox Code Playgroud)