<?php
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\RefreshDatabaseState;
use Illuminate\Contracts\Console\Kernel;
abstract class TestCase extends BaseTestCase
{
use CreatesApplication;
use RefreshDatabase;
/**
* Override the standard method and use refresh instead of fresh
*
*/
protected function refreshTestDatabase()
{
if (! RefreshDatabaseState::$migrated) {
$this->artisan('migrate:refresh', ['--seed' => true]);
$this->app[Kernel::class]->setArtisan(null);
RefreshDatabaseState::$migrated = true;
}
$this->beginDatabaseTransaction();
}
}
2条答案
按热度按时间anhgbhbe1#
当您要求Laravel创建新迁移时,它创建的文件有两种方法:
这是在运行迁移时执行的操作,以及
这是在回滚迁移(使用rollback命令或refresh命令)时执行的操作。
默认情况下,创建文件时down()方法包含的所有内容都是删除表的步骤:
因此,理论上,如果您愿意,可以通过从迁移中删除该行来防止表被删除。
但问题是,使用“refresh”命令意味着它将回滚所有迁移,然后再次运行迁移-此时,如果您仍然使用up()函数,迁移将失败,因为它试图创建一个已经存在的表(因为它还没有被删除)。
所以我认为你有两个选择:
1.从迁移中完全删除该表(并删除数据库的迁移表中对它的任何引用),以防止它受到围绕它进行的迁移的影响。
1.如果必须通过迁移来处理(也许它有键指向其他表或从其他表指向其他表),那么我会将表的内容导出为原始SQL转储,将其保存在系统上的一个文件中,然后让迁移沿着-迁移过程仍然会创建/销毁它,但在运行迁移后使用“-- seed”选项将所有数据放回其中。
kr98yfug2#
答案在评论中,但我认为值得一提。
使用
php artisan:fresh
代替刷新刷新调用
dropAllTables()
,因此如果您希望保留任何内容,请避免使用此操作全新运行所有回滚,然后运行所有迁移
这有一个附带的好处,那就是测试回滚(至少测试它们是否运行)。
然后,您可以从迁移中排除该大型表,并在其他位置管理它。
也可以将大型表作为早期迁移,仅在此点之后运行迁移
例如,仅刷新最近5次迁移
php artisan migrate:refresh --step=5
https://laravel.com/docs/9.x/migrations
您可能还希望在不删除所有表的情况下运行测试。
默认情况下,Laravel在每次测试运行时都运行
migrate:fresh
,但这可以通过使用如下的基本TestCase来避免有关RefreshDatabase的工作原理,请参阅API文档
https://github.com/laravel/framework/blob/9.x/src/Illuminate/Foundation/Testing/RefreshDatabase.php#L70