Laravel Schema::从单元测试运行时创建忽略表前缀



我有一个单元测试,它正在运行一个种子程序我已经构建了一个类的新实例。当我运行Artisan的播种机时,它运行时没有问题。然而,当单元测试完成时:

class MyClassTest extends TestCase {
    public function setUp() {
        // Setup application
        parent::setUp();
        $this->seed('MyClassSeeder');
    }

运行的以下位拒绝使用前缀

class MyClass extends Base {
    // Switch to the proper DB prefix
    protected function prefix() {
        DB::connection('main')->setTablePrefix($this->id . '_');
        return $this;
    }
    // This is run by the seeder, everything up to here works fine...
    public function setupDatabase() {
        $this->prefix();
        // This returns "1001_", which is correct
        Log::info(Schema::connection('main')->getConnection()->getTablePrefix());
        // Creates "myTable" instead of "1001_myTable"
        if(!Schema::connection('main')->hasTable('myTable')) {
             Schema::connection('main')->create('myTable', function($table) {
             ...

当我手动运行它时,它工作得很好,我甚至不知道从哪里开始查找。它甚至返回了正确的前缀,只是不使用它。其他人看到了吗?它是可复制的吗?测试环境(由单元测试自动使用)是否关闭了我已经重新启用的过滤器之外的其他功能?

如有任何帮助,我们将不胜感激。即使是复制品也至少会告诉我这不是我们的代码。我们已经进行了相当多的扩展,但在我们的安装中,Laravel代码库应该不会有重大更改。

进一步测试

所以我继续测试,发现了一个似乎是错误的东西,尽管我要进一步研究它,但我会把它发布在这里,以防它会让任何人对类似的问题产生记忆:

我修改了

Log::info(Schema::connection('main')->getConnection()->getTablePrefix());

成为

Log::info('Grammar Prefix: ' . Schema::connection('promotion')->getConnection()->getSchemaGrammar()->getTablePrefix());
Log::info('Connection Prefix: ' . Schema::connection('promotion')->getConnection()->getTablePrefix());

发现虽然连接前缀行和以前一样工作正常,但语法前缀不存在语法前缀和连接前缀不匹配虽然我可以解决这个问题,但我想知道为什么当我以除单元测试类之外的任何方式运行它时,它都保持一致,但这里存在不匹配。如果其他人看到它,很快就会报告为错误。

最终测试

据我所知,代码应该从它的数据库配置文件中获得初始设置,然后当行

DB::connection('promotion')->setTablePrefix($this->id . '_');

正在运行。我通过运行来解决这个问题

DB::connection('promotion')->getSchemaGrammar()->setTablePrefix($this->id . '_');

这似乎解决了问题。这不应该是必要的,我认为我使用的代码没有理由不具有预期的效果。我认为这是一个错误,并将在今天晚些时候报告。我会把这个问题留一段时间,以防我遗漏了什么,但我很快就会结束。

我得出的结论是这是一个bug。没有解释为什么它在一个环境中可以工作,但在另一个环境下不能工作,除非测试正在做与默认环境不同的事情,而我找不到它。

PHPUnit不会改变Laravel与数据库交互的方式。当您通过任何环境配置运行测试时,请确保您的配置没有被覆盖

还要确保您正在设置和使用相同的连接。在您提供的代码中,您正在为连接promotion设置前缀,但您正在使用连接main这是一个有效的例子,我试着让它和你的一样。

TestSeedTest.php

<?php
class TestSeedTest extends TestCase{
   public function setUp() {
        // Setup application
        parent::setUp();

    }
    public function testSeeder(){
        $this->seed('MyClassSeeder');
    }
}
?>

MyClassSeeder.php

<?php
class MyClassSeeder extends Seeder {
    private $id='123';
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $this->setupDatabase();
    }
    protected function prefix() {
        DB::connection('promotion')->setTablePrefix($this->id . '_');
        return $this;
    }

    // This is run by the seeder, everything up to here works fine...
    public function setupDatabase() {
        $this->prefix();

        if(!Schema::connection('promotion')->hasTable('myTable')) {
             Schema::connection('promotion')->create('myTable', function($table) {
                $table->increments('id');
                $table->string('test');
                $table->timestamps();
            });
        }
    }
}

最新更新