Laravel phpunit多个数据库测试未运行

时间:2018-03-01 09:45:52

标签: laravel unit-testing phpunit multi-tenant laravel-5.6

我们设置了一个多租户,其中包含一个主租户和其他租户数据库,并且在运行非sqlite测试时遇到一些问题。数据库是mysql。

目前正在尝试针对主数据库和一个租户数据库运行测试。模型构造函数中的连接设置如下:

BaseMainModel

$this->connection = config('database.main');

BaseTenantModel

$this->connection = config('database.tenant');

我观察到以下内容:

使用phpunit.xml中的以下设置在内存数据库中使用sqlite正常运行测试:

<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="APP_DEBUG" value="true"/>
<env name="DB_CONNECTION" value="testing"/>
<env name="DB_CONNECTION_TENANT" value="testing"/>

config.database.connections

    'testing' => [
        'driver' => 'sqlite',
        'database' => ':memory:',
        'prefix' => '',
    ],

然而,当在内存数据库中没有sqlite的情况下运行(因此注释掉<env name="DB_CONNECTION" value="testing"/><env name="DB_CONNECTION_TENANT" value="testing"/>的两个phpunit行)并在我的普通数据库上运行时,测试在第一次测试后开始挂起。

例如,如果我在文件SomeTests.php中有5个测试,则第一个完成,并且该过程在第二个上挂起。

如果我将protected $connectionsToTransact = ['main', 'tenant'];添加到我的TestCase课程,即使第一次测试也没有完成。

另外需要注意的是,我通过创建自己的特征并使用laravel的特征来覆盖refreshTestDatabase()特征的RefreshDatabase方法。我的特点看起来像这样:

trait RefreshDatabase
{
use BaseRefreshDatabase;

/**
 * Refresh the in-memory database.
 *
 * @return void
 */
protected function refreshInMemoryDatabase()
{
    $this->artisan('migrate');

    $path = 'database' . DIRECTORY_SEPARATOR . 'migrations' . DIRECTORY_SEPARATOR . 'tenants';

    Artisan::call('migrate', [
        '--database' => 'testing',
        '--path' => $path
    ]);

    $this->app[Kernel::class]->setArtisan(null);
}

/**
 * Refresh a conventional test database.
 *
 * @return void
 */
protected function refreshTestDatabase()
{
    if (!RefreshDatabaseState::$migrated) {

        $this->artisan('migrate:fresh');

        $path = 'database' . DIRECTORY_SEPARATOR . 'migrations' . DIRECTORY_SEPARATOR . 'tenants';

        $this->artisan('migrate:fresh', [
            '--path' => $path,
            '--database' => config('database.tenant')
        ]);

        $this->app[Kernel::class]->setArtisan(null);

        RefreshDatabaseState::$migrated = true;
    }

    $this->beginDatabaseTransaction();
}
}

我尝试在我的测试setUp函数中转储:

class RelationsTest extends TestCase
{
use RefreshDatabase;

protected function setUp()
{
    parent::setUp();
    dump("here");  // this is logged
    $this->product = factory(Product::class)->create();
    dump("product created"); // this is not. However I dumped in the model constructors and it did enter the Product constructor
    $this->someClass= factory(SomeClass::class)->create();
    $this->user = factory(User::class)->create();
    $this->otherClass = factory(OtherClass::class)->create();

    $this->yetAnotherClass= factory(YetAnotherClass::class)->create([
        'owner_id' => $this->user->id,
        'product_id' => $this->product->id,
        'someClass_id' => $this->someClass->id,
    ]);
}

有趣的是,如果我单独在文件中运行每个测试,它们运行正常。所以在我不理解的测试之间发生了一些事情!

我觉得它与我的模型连接(或其他东西)有关。因为如果我只使用assertTrue(true)运行两个基本测试(不使用工厂或触摸数据库),它们运行正常。

非常感谢帮助!谢谢:))

1 个答案:

答案 0 :(得分:0)

从php 7.1升级到php 7.2并添加此行

protected $connectionsToTransact = ['tenant'];

到我的基础测试用例似乎已经部分解决了这个问题,我可以运行一个测试类。

但是,如果我添加主连接,则测试未运行

protected $connectionsToTransact = ['main', 'tenant'];

此外,我收到错误&#34;连接太多&#34;如果我运行我的整个测试套件,即使只有protected $connectionsToTransact = ['tenant'];。我认为这是因为main在每次测试后都没有断开连接。