我有一个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>
答案 0 :(得分:1)
在lagbox和Kyslik发表评论后,我能够为这个问题创建解决方案。
我的测试套件使用SQLite,默认情况下禁用了外键,这显然是为了向后兼容。为确保测试套件与正常环境相同,我向TestCase
类添加了以下代码:
/**
* Enables foreign keys.
*
* @return void
*/
public function enableForeignKeys()
{
$db = app()->make('db');
$db->getSchemaBuilder()->enableForeignKeyConstraints();
}
接下来,我将这一行添加到同一类的setup
方法中:
$this->enableForeignKeys();
这使我能够在测试环境中使用外键。