首页 > 解决方案 > 当我利用 laravel 的 `RefreshDatabase` 特性通过 phphunit 运行数据库迁移时,Laravel 指定了一个迁移文件夹

问题描述

我正在将我的应用程序从 Codeigniter 迁移到 laravel,我们也在进行迭代和单元测试。

该数据库由2个数据库组成:

因此,我想制作一个用于old数据库的迁移脚本,但为了避免故障,我想为每个数据库的迁移脚本指定一个特定的文件夹。

因此我找到了这个工具:https ://github.com/Xethron/migrations-generator并通过这个帮助输出:

Description:
  Generate a migration from an existing table structure.

Usage:
  migrate:generate [options] [--] [<tables>]

Arguments:
  tables                              A list of Tables you wish to Generate Migrations for separated by a comma: users,posts,comments

Options:
  -c, --connection[=CONNECTION]       The database connection to use. [default: "etable_api"]
  -t, --tables[=TABLES]               A list of Tables you wish to Generate Migrations for separated by a comma: users,posts,comments
  -i, --ignore[=IGNORE]               A list of Tables you wish to ignore, separated by a comma: users,posts,comments
  -p, --path[=PATH]                   Where should the file be created?
      --defaultIndexNames             Don't use db index names for migrations
      --defaultFKNames                Don't use db foreign key names for migrations
  -h, --help                          Display this help message
  -q, --quiet                         Do not output any message
  -V, --version                       Display this application version
      --ansi                          Force ANSI output
      --no-ansi                       Disable ANSI output
  -n, --no-interaction                Do not ask any interactive question
      --env[=ENV]                     The environment the command should run under
  -tp, --templatePath[=TEMPLATEPATH]  The location of the template for this generator
  -v|vv|vvv, --verbose                Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

我可以使用以下命令序列为迁移脚本创建一个专用文件夹:

mkdir -p ./database/migration/old
php artisan migrate:generate -c old -p ./database/migration/old

通过工匠,我可以通过以下方式运行迁移:

php artisan migrate -c old -p ./database/migration/old

因此我可以使用 laravel 提供的解决方案:

namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;

class ExampleTest extends TestCase
{
    use RefreshDatabase;

    /**
     * A basic functional test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
      // Do some fancy stuff here
    }
}

但是如何在使用时为要参与测试的数据库的迁移脚本指定指定的文件夹Illuminate\Foundation\Testing\RefreshDatabase

标签: phplaravelcodeigniterphpunitdatabase-migration

解决方案


我看到这个问题有点老了,但如果其他人正在寻找这个问题的答案,这对我有用。您可以通过对应用程序进行一些调整来完成您想要做的事情。

我在尝试对具有迁移子文件夹的应用程序运行测试时发现的两个问题是,当构建应用程序以及通过 RefreshDatabase 特征刷新数据库时,子文件夹中的迁移不会被执行。

为了让它工作,我必须:

  1. 修改我的 CreatesApplication 特征以在创建应用程序后在子文件夹中运行迁移。
  2. 创建我自己的RefreshDatabase特征,以搭载包含的RefreshDatabase特征。

RefreshDatabase 特征

  • 在 tests/Traits 目录下创建一个新文件(我必须创建它),RecursiveRefreshDatabase.php 该文件包含以下代码:
<?php

namespace Tests\Traits;

use Illuminate\Contracts\Console\Kernel;
use Illuminate\Foundation\Testing\RefreshDatabase;

trait RecursiveRefreshDatabase {
    use RefreshDatabase;

    /**
     * Refresh the in-memory database.
     *
     * @return void
     */
    protected function refreshInMemoryDatabase()
    {
        $this->artisan('migrate');
        // 'database/migrations/sub-folder’ would probably be ‘database/migrations/old’ in the case of the OP
        $this->artisan('migrate', ['--path' => 'database/migrations/sub-folder’]);

        $this->app[Kernel::class]->setArtisan(null);
    }
}
  • 在您的测试中替换
use Illuminate\Foundation\Testing\RefreshDatabase;

use Tests\Traits\RecursiveRefreshDatabase as RefreshDatabase;
  • 注意:我将覆盖refreshInMemoryDatabase本示例中的方法,但如果您不使用内存数据库进行测试,您可能需要覆盖不同的方法。

修改 CreatesApplication.php

  • 修改文件tests/CreatesApplication.php 以调用您的子文件夹迁移 createApplication() 如下所示
public function createApplication()
{
    $app = require __DIR__ . ‘/../../bootstrap/app.php’;

    $app->make(Kernel::class)->bootstrap();

    $this->afterApplicationCreated(function () {
        // 'database/migrations/sub-folder’ would probably be ‘database/migrations/old’ in the case of the OP
        $this->artisan(‘migrate’, [‘—path’ => ‘database/migrations/sub-folder’]);
    });

    return $app;
}



这些更改对我有用,并让我的测试再次工作。请让我知道这对你有没有用!


推荐阅读