【问题标题】:Laravel tests fail after a simple migration简单迁移后 Laravel 测试失败
【发布时间】:2016-06-28 14:03:02
【问题描述】:

我正在使用 Laravel 创建一个项目,今天我遇到一个问题,我找不到如何以“正确”的方式解决。

我有这个迁移类:

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class AddCityAndCountryColumnToClient extends Migration {
    public function up() {
        Schema::table('clients', function (Blueprint $table) {
            $table->string('city')->nullable()->default(null);
            $table->string('country', 2)->nullable()->default(null);
        });
    }

    public function down() {
        Schema::table('clients', function (Blueprint $table) {
            $table->dropColumn('country');
            $table->dropColumn('city');
        });
    }
}

我有一堆基于该表“客户端”模型的测试,它们运行得非常好,但是在我添加了这个迁移之后,我的测试从一开始就每次都失败。

现在,我发现如果我将迁移类修改为:

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class AddCityAndCountryColumnToClient extends Migration {
    public function up() {
        Schema::table('clients', function (Blueprint $table) {
            $table->string('city')->nullable()->default(null);
            $table->string('country', 2)->nullable()->default(null);
        });
    }

    public function down() {
        Schema::table('clients', function (Blueprint $table) {
            // $table->dropColumn('country');
            // $table->dropColumn('city');
        });
    }
}

现在我的所有测试都运行良好。但我担心“down”方法现在实际上什么都不做,而它本应与“up”方法相反。

出于速度目的,我的测试数据库是内存中的 sqlite 实例:

'sqlite_testing' => [
    'driver'   => 'sqlite',
    'database' => ':memory:',
    'prefix'   => '',
],

我还有另外两个具有相同行为的迁移。奇怪的是,我已经在其中一个表中做了这样的事情(添加了一个字符串列),而且我不需要在那个类上评论我的“down”方法的内容:

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class AddPhotoColumnToClientsTable extends Migration
{
    public function up()
    {
        Schema::table('clients', function (Blueprint $table) {
            $table->string('photo')->nullable();
        });
    }

    public function down()
    {
        Schema::table('clients', function (Blueprint $table) {
            $table->dropColumn('photo');
        });
    }
}

所以我不知道在第一次提到的迁移中添加的“城市”和“国家”列有什么问题。

我从 php artisan 命令行创建了所有这些迁移类,因此我没有修改它们的默认结构(这里的示例没有 cmets 来缩短它们),并且我还检查了这些迁移中没有一个有错误的代码关于“向下”方法。

我是否遗漏了什么,或者我忘记了 SQLite 或迁移的某种限制?

下面是注释掉“down”方法的结果:

PHPUnit 4.8.23 by Sebastian Bergmann and contributors.

.............S.............................................

Time: 42.4 seconds, Memory: 47.25Mb

OK, but incomplete, skipped, or risky tests!
Tests: 59, Assertions: 215, Skipped: 1.

如果我取消注释任何或所有“向下”方法内容行,这就是结果:

PHPUnit 4.8.23 by Sebastian Bergmann and contributors.

E

Time: 1.74 seconds, Memory: 20.75Mb

There was 1 error:

1) AuthTest::a_client_user_can_login_via_api
Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1 no such column: country (SQL: CREATE TEMPORARY TABLE __temp__clients AS SELECT id, user_id, cell_phone, photo, created_at, updated_at, deleted_at, country FROM clients)

C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Connection.php:669
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Connection.php:629
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Connection.php:409
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Schema\Blueprint.php:83
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Schema\Builder.php:203
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Schema\Builder.php:128
C:\My Project\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php:221
C:\My Project\database\migrations\2016_03_12_002857_add_city_and_country_column_to_client.php:28
C:\My Project\database\migrations\2016_03_12_002857_add_city_and_country_column_to_client.php:28
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Migrations\Migrator.php:233
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Migrations\Migrator.php:181
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Console\Migrations\RollbackCommand.php:63
C:\My Project\vendor\laravel\framework\src\Illuminate\Container\Container.php:507
C:\My Project\vendor\laravel\framework\src\Illuminate\Console\Command.php:169
C:\My Project\vendor\symfony\console\Command\Command.php:256
C:\My Project\vendor\laravel\framework\src\Illuminate\Console\Command.php:155
C:\My Project\vendor\symfony\console\Application.php:791
C:\My Project\vendor\symfony\console\Application.php:186
C:\My Project\vendor\symfony\console\Application.php:117
C:\My Project\vendor\laravel\framework\src\Illuminate\Console\Application.php:64
C:\My Project\vendor\laravel\framework\src\Illuminate\Foundation\Console\Kernel.php:159
C:\My Project\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\InteractsWithConsole.php:25
C:\My Project\vendor\laravel\framework\src\Illuminate\Foundation\Testing\DatabaseMigrations.php:12
C:\My Project\vendor\laravel\framework\src\Illuminate\Foundation\Testing\TestCase.php:127
C:\Users\TheWindowsUser\AppData\Roaming\Composer\vendor\phpunit\phpunit\src\TextUI\Command.php:149
C:\Users\TheWindowsUser\AppData\Roaming\Composer\vendor\phpunit\phpunit\src\TextUI\Command.php:100

Caused by
PDOException: SQLSTATE[HY000]: General error: 1 no such column: country

C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Connection.php:408
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Connection.php:662
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Connection.php:629
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Connection.php:409
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Schema\Blueprint.php:83
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Schema\Builder.php:203
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Schema\Builder.php:128
C:\My Project\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php:221
C:\My Project\database\migrations\2016_03_12_002857_add_city_and_country_column_to_client.php:28
C:\My Project\database\migrations\2016_03_12_002857_add_city_and_country_column_to_client.php:28
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Migrations\Migrator.php:233
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Migrations\Migrator.php:181
C:\My Project\vendor\laravel\framework\src\Illuminate\Database\Console\Migrations\RollbackCommand.php:63
C:\My Project\vendor\laravel\framework\src\Illuminate\Container\Container.php:507
C:\My Project\vendor\laravel\framework\src\Illuminate\Console\Command.php:169
C:\My Project\vendor\symfony\console\Command\Command.php:256
C:\My Project\vendor\laravel\framework\src\Illuminate\Console\Command.php:155
C:\My Project\vendor\symfony\console\Application.php:791
C:\My Project\vendor\symfony\console\Application.php:186
C:\My Project\vendor\symfony\console\Application.php:117
C:\My Project\vendor\laravel\framework\src\Illuminate\Console\Application.php:64
C:\My Project\vendor\laravel\framework\src\Illuminate\Foundation\Console\Kernel.php:159
C:\My Project\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\InteractsWithConsole.php:25
C:\My Project\vendor\laravel\framework\src\Illuminate\Foundation\Testing\DatabaseMigrations.php:12
C:\My Project\vendor\laravel\framework\src\Illuminate\Foundation\Testing\TestCase.php:127
C:\Users\TheWindowsUser\AppData\Roaming\Composer\vendor\phpunit\phpunit\src\TextUI\Command.php:149
C:\Users\TheWindowsUser\AppData\Roaming\Composer\vendor\phpunit\phpunit\src\TextUI\Command.php:100

FAILURES!
Tests: 1, Assertions: 4, Errors: 1.

更新

顺便说一句,我正在使用 use Illuminate\Foundation\Testing\DatabaseMigrations; 特征运行我的所有测试。 Laravel 提供的默认测试类没有应用特殊配置或特殊更改。

【问题讨论】:

    标签: php sqlite phpunit migration laravel-5.2


    【解决方案1】:

    要么将 drop 拆分为两个单独的操作,要么将一个数组交替传递给要删除的列的 dropColumn。

    要么

    Schema::table('clients', function (Blueprint $table) {
        $table->dropColumn('country');
    });
    
    Schema::table('clients', function (Blueprint $table) {
        $table->dropColumn('city');
    });
    

    $table->dropColumn(['country', 'city']);
    

    https://github.com/laravel/framework/issues/2979

    【讨论】:

    • 对于遇到此问题的任何其他人,此解决方案有效,应标记为答案。我将要删除的每一列添加为数组的一部分 $table-&gt;dropColumn(['country', 'city']);
    猜你喜欢
    • 2015-02-05
    • 1970-01-01
    • 2020-09-07
    • 1970-01-01
    • 2021-11-20
    • 2016-02-16
    • 2017-05-26
    • 1970-01-01
    相关资源
    最近更新 更多