代码之家  ›  专栏  ›  技术社区  ›  Douwe de Haan

phpunit忽略laravel中的ondelete集空值

  •  1
  • Douwe de Haan  · 技术社区  · 8 年前

    我有一个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]);
        }
    
    }
    

    PHPUNITIT.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 回复  |  直到 8 年前
        1
  •  1
  •   Douwe de Haan    8 年前

    在Lagbox和Kyslik的评论之后,我能够为这个问题创建一个解决方案。

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

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

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

    $this->enableForeignKeys();
    

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