потому что тест не работает, phpunit в laravel? - PullRequest
0 голосов
/ 06 августа 2020

У меня есть следующие настройки:

config / database. php

конкретно в: 'connections'

'testing' => [
            'driver'            => 'mysql',
            'url'               => env('DATABASE_URL'),
            'host'              => env('TEST_DB_HOST'),
            'port'              => env('TEST_DB_PORT', '5432'),
            'database'          => env('TEST_DB_DATABASE', 'forge'),
            'username'          => env('TEST_DB_USERNAME', 'forge'),
            'password'          => env('TEST_DB_PASSWORD', ''),
            'charset'           => 'utf8',
            'prefix'            => '',
            'prefix_indexes'    => true,
            'schema'            => 'public',
            'sslmode'           => 'prefer'
        ],

в .env

TEST_DB_CONECTION=testing
TEST_DB_HOST=mysql-db
TEST_DB_PORT=3306
TEST_DB_DATABASE=db_test
TEST_DB_USERNAME=root
TEST_DB_PASSWORD=secret_test

весь мой файл 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="true"
         stopOnFailure="false">
    <testsuites>
        <testsuite name="Feature">
            <directory suffix="Test.php">./tests/Feature</directory>
        </testsuite>

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

внутри моего тестового класса

    use RefreshDatabase;
    protected $user;
    public function setUp() : void {
        parent::setUp();
        $this->user = factory(User::class)->create();
        $this->actingAs($this->user);
    }
    public function testCreateExcessCarriers(){
    var_dump("some text to try");
    }

и при выполнении:

docker-compose exec utraq vendor/bin/phpunit tests/Unit/Http/Controllers/ECControllerTest.php --filter testCreateExcessCarriers

I получите эту ошибку:

Illuminate \ Database \ QueryException: SQLSTATE [HY000]: Общая ошибка: 1 Невозможно добавить столбец NOT NULL со значением по умолчанию NULL (SQL: изменить таблицу "пользователи "add column" agency_id "integer not null)

таким образом я настроил фабрику, проверяя модель, все в порядке

$factory->define(App\Models\User::class, function (Faker $faker) {
    static $password;

    return [
        'uuid' => $faker->uuid,
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'password' => $password ?: $password = bcrypt('secret'),

        'active' => 1,
        'agency_id' => 3,
    ];
});

Однако я не знаю почему я получаю эту ошибку после выполнения команды. Как я могу это исправить?

РЕДАКТИРОВАТЬ: Миграция, при которой я думаю, я получаю ошибку. Для таблицы «Пользователи» существует 2 миграции.

Миграция 1:

 Schema::create('users', function (Blueprint $table) {
                $table->increments('id');
                $table->string('uuid');
                $table->string('name');
                $table->string('email')->unique();
                $table->string('password');
                $table->string('address1')->nullable(); //Address 1
                $table->string('address2')->nullable(); //Address 2
                $table->string('city')->nullable(); //City
                $table->string('state_name')->nullable(); //State
                $table->integer('state_id')->nullable(); //State
                $table->string('zip_code', 10)->nullable(); //Zip Code    
                $table->string('employee_type')->nullable();
                $table->dateTime('last_logged_in')->nullable();
                $table->json('dashboard')->nullable();
                $table->rememberToken();
                $table->timestamps();
            });

Миграция 2: Как видите, здесь назначено поле agency_id

 Schema::table('users', function (Blueprint $table) {
                $table->integer('agency_id')->after('password');
                $table->boolean('active')->after('remember_token')->default('0');
                $table->boolean('verified')->after('active')->default(false);
                $table->string('avatar')->nullable();
            });

Ответы [ 3 ]

2 голосов
/ 06 августа 2020

Исходя из вашего вопроса, я полагаю, вы действительно хотите использовать свою тестовую базу данных mysql, которую вы определили как «тестовое» соединение.

Но в вашей конфигурации phpunint вы используете

<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value="db_test"/>

Что явно относится к соединению sqlite. Другие уже указали на проблемы с sqlite и добавлением столбцов, не допускающих значения NULL

Вероятно, вы захотите изменить свое соединение и удалить запись DB_DATABASE

<env name="DB_CONNECTION" value="testing"/>

EDIT:

TEST_DB_CONECTION=testing

Кажется, нигде не используется? Тоже опечатка :) - может и из вашего env удалить

0 голосов
/ 07 августа 2020

По моему опыту, это сводится к тому, что sqlite не может добавить столбец, не допускающий значение NULL, в существующую таблицу без значения по умолчанию.

Мы используем обходной путь, чтобы разделить миграцию в 2 этапа в рамках одной миграции. Первый шаг добавляет столбец как допускающий значение NULL, а следующий шаг обновляет его так, чтобы он не допускал значения NULL.

Таким образом, ваша миграция будет выглядеть примерно так (не проверено):

Schema::table('users', function (Blueprint $table) {
    $table->integer('agency_id')->nullable()->after('password');
});
Schema::table('users', function (Blueprint $table) {
    $table->integer('agency_id')->nullable(false)->change();
});

Это принцип, что мы используем, но может не работать во всех случаях использования. Возможно, вы захотите установить значение по умолчанию на первом шаге вместо того, чтобы делать его допускающим значение NULL, если это лучше подходит для вашего варианта использования.

Если я правильно помню, аргумент false в nullable(false) стал доступен только позже в Laravel 5.x, поэтому это может не работать в зависимости от версии Laravel, с которой вы работаете.

0 голосов
/ 06 августа 2020

См. Этот ответ; { ссылка }

Кажется, что SQLite просто оставляет вас в плохом состоянии, если вам нужно добавить столбец, не допускающий значения NULL, в существующую таблицу, в котором столбец также не должен иметь значение по умолчанию

Короче говоря, для решения проблемы у вас есть 3 возможности:

  • Используйте тот же DB engine , который вы используете в производстве для запуска вашего тесты. Это медленнее, но вы обязательно столкнетесь с теми же проблемами, если они есть.
  • Изменить на допускающий значение NULL: $table->integer('agency_id')->nullable()->after('password');
  • (я бы абсолютно не рекомендовал, так как это внешний ключ) Добавьте значение по умолчанию: $table->integer('agency_id')->default(1)->after('password');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...