我们设置了一个主数据库和其他租户数据库的多租户,并且在运行非 SQLite 测试时遇到了一些问题。数据库是mysql。
目前正在尝试针对主数据库和一个租户数据库运行测试。模型构造函数中的连接设置如下:
基本主模型
$this->connection = config('database.main');
基本租户模型
$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 运行时(因此注释掉我的两个 phpunit 行<env name="DB_CONNECTION" value="testing"/>
和<env name="DB_CONNECTION_TENANT" value="testing"/>
)并在我的普通数据库上运行时,测试在第一次测试后开始挂起。
因此,例如,如果我在一个文件中有 5 个测试SomeTests.php
,则第一个完成,并且该过程挂在第二个上。
如果我将其添加protected $connectionsToTransact = ['main', 'tenant'];
到我的TestCase
班级,即使是第一个测试也不会完成。
另一件需要注意的事情是,我通过创建自己的 trait 并使用 laravel 的 trait 来覆盖 trait 的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)
使用(不使用工厂或接触数据库)运行两个基本测试,它们运行良好。
非常感谢您的帮助!谢谢 :)