简体   繁体   English

当我使用 Laravel 的 `RefreshDatabase` 特性通过 phphunit 运行数据库迁移时,Laravel 指定一个迁移文件夹

[英]Laravel specify a migration folder when I run the database migrations via phphunit utilizing the laravel's `RefreshDatabase` trait

I am migrating my application from Codeigniter into laravel, also we are in the process of making itegration and unit tests as well.我正在将我的应用程序从 Codeigniter 迁移到 Laravel,我们也在进行迭代和单元测试。

The database is consisted of 2 databases:数据库由2个数据库组成:

  • old That is the one used from the original codeigniter. old那是原始 codeigniter 中使用的那个。
  • new That is used for other features not related in the codeingiter project. new用于 codeingiter 项目中不相关的其他功能。

Therefore I want to make a migration script used for the old database, but in order to avoid breakdowns I want to specify a specific folder for the migration scripts for each database.因此,我想为old数据库制作一个迁移脚本,但为了避免故障,我想为每个数据库的迁移脚本指定一个特定文件夹。

Therefore I found this tool: https://github.com/Xethron/migrations-generator and via this help output:因此我找到了这个工具: 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

I can use the following command sequence in order to make a dedicated folder for the migration script:我可以使用以下命令序列为迁移脚本创建一个专用文件夹:

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

And via artisan I can run the migrations via:通过工匠,我可以通过以下方式运行迁移:

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

Therefore I can use the laravel provided solution:因此我可以使用 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
    }
}

But how I can specify the specified folder for the migration script of the database that I want to participate in test when using the Illuminate\\Foundation\\Testing\\RefreshDatabase ?但是,如何在使用Illuminate\\Foundation\\Testing\\RefreshDatabase时为要参与测试的数据库的迁移脚本指定指定文件夹?

I see this question is somewhat old but if anyone else is looking for the answer to this problem this is what worked for me.我看到这个问题有点老了,但如果其他人正在寻找这个问题的答案,这对我有用。 You can accomplish what you're trying to do with a few tweaks to your application.您可以通过对应用程序进行一些调整来完成您想要做的事情。

The two problems I found when trying to run tests against an application with a migrations sub folder is that when the application is built and when the database is refreshed by the RefreshDatabase trait the migrations in the sub folder do not get executed.我在尝试对具有迁移子文件夹的应用程序运行测试时发现的两个问题是,当构建应用程序和通过 RefreshDatabase trait 刷新数据库时,子文件夹中的迁移不会被执行。

To get it to work I had to:为了让它工作,我必须:

  1. Modify my CreatesApplication trait to run the migrations in the sub folder after the application is created.创建应用程序后,修改我的 CreatesApplication trait 以在子文件夹中运行迁移。
  2. Create my own RefreshDatabase trait that would piggy-back on the included RefreshDatabase trait.创建我自己的RefreshDatabase特征,该特征将搭载在包含的RefreshDatabase特征上。

RefreshDatabase trait刷新数据库特性

  • Create a new file under tests/Traits directory (I had to create this) called RecursiveRefreshDatabase.php This file contains the following code:在 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);
    }
}
  • In your tests replace在您的测试中替换
use Illuminate\Foundation\Testing\RefreshDatabase;

with

use Tests\Traits\RecursiveRefreshDatabase as RefreshDatabase;
  • Note: I am overriding the refreshInMemoryDatabase method in this example but you may need to override a different one if you are not using an in memory database for testing.注意:我在本例中覆盖了refreshInMemoryDatabase方法,但如果您不使用内存数据库进行测试,则可能需要覆盖refreshInMemoryDatabase方法。

Modify CreatesApplication.php修改 CreatesApplication.php

  • Modify the file tests/CreatesApplication.php to call your sub folder migrations the createApplication() as seen below修改文件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;
}



These changes worked for me and got my tests working again.这些更改对我有用,并使我的测试再次运行。 Let me know if it works for you!请让我知道这对你有没有用!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM