PHPunit忽略Laravel中的onDelete设置为空

时间:2018-07-25 08:40:12

标签: laravel phpunit

我有一个Laravel设置,尝试使用测试驱动开发来构建所有内容。

设置

我进行了迁移,在其中创建了一个类别表,该表可以是其他类别的父项或子项。当我删除父类别时,所有子类别都应成为根类别。为此,我创建了一个外键,该外键具有set null作为onDelete的值。

问题

当我在MySQL中测试此行为时,它可以按预期工作,但是当我使用PHPunit运行测试时,它会失败。谁能帮助我弄清楚我在哪里犯了错误,或者根本不可能吗?

迁移

Schema::create('categories', function(Blueprint $table) {
    $table->increments('id');

    $table->string('name', 100);

    $table->unsignedInteger('parent_id')->nullable();

    $table->timestamps();

    $table->foreign('parent_id')->references('id')->on('categories')->onDelete('set null');
});

测试文件

namespace Tests\Unit;

use App\Models\Category;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;

class CategoryTest extends TestCase
{
    /**
     * @test
     */
    public function aCategoryBecomesRootWhenParentIsDeleted()
    {
        $category = Category::create(['name' => 'test_category_6']);

        $child_category = Category::create(['name' => 'test_category_7', 'parent_id' => $category->id]);

        $category->delete();

        $this->assertDatabaseHas('categories', ['id' => $child_category->id, 'parent_id' => NULL]);
    }

}

phpunit.xml

<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
         backupStaticAttributes="false"
         bootstrap="vendor/autoload.php"
         colors="true"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         processIsolation="false"
         stopOnFailure="false">
    <testsuites>
        <testsuite name="Unit">
            <directory suffix="Test.php">./tests/Unit</directory>
        </testsuite>

        <testsuite name="Feature">
            <directory suffix="Test.php">./tests/Feature</directory>
        </testsuite>
    </testsuites>
    <filter>
        <whitelist processUncoveredFilesFromWhitelist="true">
            <directory suffix=".php">./app</directory>
        </whitelist>
    </filter>
    <php>
        <env name="APP_ENV" value="testing"/>
        <env name="BCRYPT_ROUNDS" value="4"/>
        <env name="DB_CONNECTION" value="sqlite"></env>
        <env name="DB_DATABASE" value=":memory:"></env>
        <env name="CACHE_DRIVER" value="array"/>
        <env name="SESSION_DRIVER" value="array"/>
        <env name="QUEUE_DRIVER" value="sync"/>
        <env name="MAIL_DRIVER" value="array"/>
    </php>
</phpunit>

1 个答案:

答案 0 :(得分:1)

在lagbox和Kyslik发表评论后,我能够为这个问题创建解决方案。

我的测试套件使用SQLite,默认情况下禁用了外键,这显然是为了向后兼容。为确保测试套件与正常环境相同,我向TestCase类添加了以下代码:

/**
 * Enables foreign keys.
 *
 * @return void
 */
public function enableForeignKeys()
{
    $db = app()->make('db');
    $db->getSchemaBuilder()->enableForeignKeyConstraints();
}

接下来,我将这一行添加到同一类的setup方法中:

$this->enableForeignKeys();

这使我能够在测试环境中使用外键。