我有一個Laravel 5.4應用程序,它具有指向不同數據庫連接的模型。Laravel 5:處理多個連接和測試
例如,我有User
指向一個MySQL數據庫,然後Company
指向一個PostgreSQL數據庫(使用$connection
變量)。
現在,當我運行PHPUnit時,我想$connection
變量被替換爲phpunit.xml
文件中指定的內容,該文件是內存類型的數據庫中的SQLite。
這是如何實現的?
我有一個Laravel 5.4應用程序,它具有指向不同數據庫連接的模型。Laravel 5:處理多個連接和測試
例如,我有User
指向一個MySQL數據庫,然後Company
指向一個PostgreSQL數據庫(使用$connection
變量)。
現在,當我運行PHPUnit時,我想$connection
變量被替換爲phpunit.xml
文件中指定的內容,該文件是內存類型的數據庫中的SQLite。
這是如何實現的?
關閉我的頭頂,你可以在模型中移動連接名稱到.ENV文件
:
public function __construct(array $attributes = [])
{
$this->connection = env('MY_CONNECTION');
parent::__construct($attributes);
}
在.ENV文件
MY_CONNECTION=mysql
PHPUnit中.xml
<env name="MY_CONNECTION" value="sqlite"/>
您不必將所有連接字符串移動到'.env'文件。更好地檢查是否存在「MY_CONNECTION」。如果是這樣,你可以覆蓋連接變量。 – mimo
個像阿圖羅·羅哈斯在他的回答中寫道,你必須在構造函數來檢查,如果連接變量被改寫:
public function __construct(array $attributes = [])
{
if(App::environment() == 'testing') {
$this->connection = env('DB_CONNECTION');
}
parent::__construct($attributes);
}
在你phpunit.xml
你需要這些變量(DB_DATABASE
可選):
<php>
<env name="APP_ENV" value="testing"/>
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value="testDatabase"/>
<php>
Laravel然後將使用來自/config/database.php
的sqllite連接
我寧可不觸摸生產代碼,而是使用服務容器來創建特定於測試的服務。
在這種情況下,如果您希望您的所有車型使用相同的默認測試連接:
public function createApplication()
{
$app = require __DIR__.'/../bootstrap/app.php';
$app->make(Kernel::class)->bootstrap();
$fakeManager = new class ($app, $app['db.factory']) extends DatabaseManager {
public function connection($name = null) {
return parent::connection($this->getDefaultConnection());
}
};
$app->instance('db', $fakeManager);
Model::setConnectionResolver($fakeManager);
return $app;
}
(這將覆蓋CreatesApplication
特質,你可以改爲放置此代碼時,應用程序的自舉和之間的任何位置當調用遷移命令時)。
(也請注意,這是使用PHP 7內聯匿名類,也可以將假數據庫管理器定義爲單獨的類)。
如前所述,您首先需要在每個模型中設置連接。 因此,您在數據庫配置文件中設置連接,在.env
文件中設置值,並在模型的構造函數中使用這些值。
對於測試,你也可以這樣做。 將測試連接添加到config/database.php
文件,然後使用重寫的env文件。
創建一個額外的env文件,將其命名爲.env.testing
。
所以,在你.env
文件,你將有:
CONNECTION_MYSQL=mysql
CONNECTION_POSTGRESS=postgress
然後在.env.testing
文件,你可以有:
CONNECTION_MYSQL=test_sqlite
CONNECTION_POSTGRESS=test_sqlite
最後加載該ENV文件時測試,去CreatesApplication
特質並更新到以下內容:
public function createApplication()
{
$app = require __DIR__.'/../bootstrap/app.php';
$app->loadEnvironmentFrom('.env.testing');
$app->make(Kernel::class)->bootstrap();
return $app;
}
通過使用loadEnvironemtFrom()
方法,所有使用此特徵的測試將加載.env.testing
文件並使用此處定義的連接。
爲什麼給定的答案不適合你的問題? – mimo