2017-06-06 138 views
3

我正在開發一個具有多個數據庫訪問的應用程序,我想用這個PHPUnit測試。我目前的做法是在config\databases.php有多個連接(mysql,mysql2,mysql3),這樣我可以在env文件中爲它們設置不同的訪問權限。因此,這些型號具有定義的變量$connection。在我的第一個功能測試中,我想訪問一個頁面,只是看到我在工廠提供的數據,只是爲了讓事情開始。在我的phpunit.xml文件中,我指定DB_CONNECTIONsqlite,並且對於每個MySql設置都有value=":memory:"Laravel多個數據庫PHPUnit

以後編輯

<php> 
    <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="DB_CONNECTION" value="sqlite"/> 
    <env name="DB_DATABASE_1" value=":memory:"/> 
    <env name="DB_DATABASE_2" value=":memory:"/> 
    <env name="DB_DATABASE_3" value=":memory:"/> 
</php> 

所以上面可以找到PHPUnit的相關代碼。

.ENV

DB_CONNECTION=mysql 
DB_HOST=127.0.0.1 
DB_PORT=3306 
DB_DATABASE=db1 
DB_USERNAME=xxx 
DB_PASSWORD=xxx 

DB_HOST_2=127.0.0.1 
DB_PORT_2=3306 
DB_DATABASE_2=db2 
DB_USERNAME_2=xxx 
DB_PASSWORD_2=xxx 

DB_HOST_2=127.0.0.1 
DB_PORT_2=3306 
DB_DATABASE_3=db3 
DB_USERNAME_3=xxx 
DB_PASSWORD_3=xxx 

,我已經是事實,當我運行的測試,我有這個錯誤的問題 - >PDOException: SQLSTATE[HY000] [1049] Unknown database ':memory:'

因此,不知何故Laravel不解析內存價值。任何建議將不勝感激。 謝謝

+0

你的意思是你有每個MySQL的設置值=的:內存:? – Devon

+0

您可以請發佈一些相關的代碼(測試和配置)? –

+0

您需要發佈您的數據庫配置文件,因爲我假設您考慮使用'DB_DATABASE_1','DB_DATABASE_2'和'DB_DATABASE_3'而不是'DB_DATABASE'做了一些重大修改。 – Devon

回答

2

我有同樣的問題,但我得到了一些help from Adam Wathan on Twitter的工作。

這裏就是我所做的:

phpunit.xml

<env name="DB_CONNECTION" value="sqlite"/> 
<env name="DB_DATABASE" value=":memory:"/> 
<env name="DB_CONNECTION_ACTIVITY_LOG" value="sqlite"/> 
<env name="DB_DATABASE_ACTIVITY_LOG" value=":memory:"/> 

config/database.php

'sqlite' => [ 
    'driver' => 'sqlite', 
    'database' => env('DB_DATABASE', database_path('database.sqlite')), 
    'prefix' => '', 
], 

'mysql' => [ 
    'driver' => env('DB_CONNECTION', 'mysql'), 
    'host' => env('DB_HOST', '127.0.0.1'), 
    'port' => env('DB_PORT', '3306'), 
    'database' => env('DB_DATABASE', 'forge'), 
    'username' => env('DB_USERNAME', 'forge'), 
    'password' => env('DB_PASSWORD', ''), 
    'unix_socket' => env('DB_SOCKET', ''), 
    'charset' => 'utf8mb4', 
    'collation' => 'utf8mb4_unicode_ci', 
    'prefix' => '', 
    'strict' => true, 
    'engine' => null, 
], 

'mysql-activity-log' => [ 
    'driver' => env('DB_CONNECTION_ACTIVITY_LOG', 'mysql'), 
    'host' => env('DB_HOST_ACTIVITY_LOG', '127.0.0.1'), 
    'port' => env('DB_PORT_ACTIVITY_LOG', '3306'), 
    'database' => env('DB_DATABASE_ACTIVITY_LOG', 'forge'), 
    'username' => env('DB_USERNAME_ACTIVITY_LOG', 'forge'), 
    'password' => env('DB_PASSWORD_ACTIVITY_LOG', ''), 
    'unix_socket' => env('DB_SOCKET_ACTIVITY_LOG', ''), 
    'charset' => 'utf8mb4', 
    'collation' => 'utf8mb4_unicode_ci', 
    'prefix' => '', 
    'strict' => true, 
    'engine' => null, 
], 

.env

DB_CONNECTION=mysql 
DB_HOST=127.0.0.1 
DB_PORT=3306 
DB_DATABASE=my-app 
DB_USERNAME=root 
DB_PASSWORD= 

DB_CONNECTION_ACTIVITY_LOG=mysql-activity-log 
DB_HOST_ACTIVITY_LOG=127.0.0.1 
DB_PORT_ACTIVITY_LOG=3306 
DB_DATABASE_ACTIVITY_LOG=my-app 
DB_USERNAME_ACTIVITY_LOG=root 
DB_PASSWORD_ACTIVITY_LOG= 

另外,對於任何未達到PDOException的人員,請確保也在您的遷移/模型中設置連接。

database/migrations/my_migration.php

Schema::connection(env('DB_CONNECTION_ACTIVITY_LOG', 'mysql'))->create(...); 

app/MyModel.php

class MyModel extends Model 
{ 
    public function __construct($attributes = []) 
    { 
     parent::__construct($attributes); 
     $this->connection = config('app.env') === 'testing' ? 'sqlite' : 'mysql-activity-log'; 
    } 
    ... 
} 
0

難以解碼的地方你實際上把:memory:的值。

在phpunit.xml <php>部分,這應該是足夠了(假設你沒有修改SQLite的連接):

<php> 
    <env name="DB_CONNECTION" value="sqlite"/> 
    <env name="DB_DATABASE" value=":memory:"/> 
</php> 
0

要解決類似的問題,我用的模型類的性狀。

在我phpunit.xml我有這樣的代碼

<env name="DB_CONNECTION" value="sqlite_testing"/> 
<env name="DB_DATABASE" value=":memory:"/>``` 

在我的config/database.php中的文件我已經建立了爲每個數據庫的連接,以及sqlite_testing連接設置爲測試

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

'mysql_connection_a' => [ 
     'driver' => 'mysql', 
     'host' => env('DB_HOST', '127.0.0.1'), 
     'port' => env('DB_PORT', '3306'), 
     'database' => env('DB_DATABASE', 'forge'), 
     'username' => env('DB_USERNAME', 'forge'), 
     'password' => env('DB_PASSWORD', ''), 
     'unix_socket' => env('DB_SOCKET', ''), 
     'charset' => 'utf8mb4', 
     'collation' => 'utf8mb4_unicode_ci', 
     'prefix' => '', 
     'strict' => true, 
     'engine' => null, 
    ], 

'mysql_connection_b' => [ 
     'driver' => 'mysql', 
     'host' => env('DB_HOST', '127.0.0.1'), 
     'port' => env('DB_PORT', '3306'), 
     'database' => env('DB_DATABASE_B', 'forge'), 
     'username' => env('DB_USERNAME', 'forge'), 
     'password' => env('DB_PASSWORD', ''), 
     'unix_socket' => env('DB_SOCKET', ''), 
     'charset' => 'utf8mb4', 
     'collation' => 'utf8mb4_unicode_ci', 
     'prefix' => '', 
     'strict' => true, 
     'engine' => null, 
    ], 

'mysql_connection_c' => [ 
     'driver' => 'mysql', 
     'host' => env('DB_HOST', '127.0.0.1'), 
     'port' => env('DB_PORT', '3306'), 
     'database' => env('DB_DATABASE_C', 'forge'), 
     'username' => env('DB_USERNAME', 'forge'), 
     'password' => env('DB_PASSWORD', ''), 
     'unix_socket' => env('DB_SOCKET', ''), 
     'charset' => 'utf8mb4', 
     'collation' => 'utf8mb4_unicode_ci', 
     'prefix' => '', 
     'strict' => true, 
     'engine' => null, 
    ], 

然後,我爲每個連接創建一個特徵來設置連接並將它們包含在相關模型中。例如如果用戶模型需要使用mysql_connection_a我會用ConnectionATrait模型

use App\Traits\ConnectionATrait; 

class User extends Authenticatable 
{ 
    use Notifiable, ConnectionATrait; 

的特質會再看看這樣

trait ConnectionATrait 
{ 
    /** 
    * The database table used by the model. 
    * 
    * @var string 
    */ 

    public function __construct(array $attributes = []) 
    { 
     parent::__construct($attributes); 
     if (env('APP_ENV') != 'testing') { 
      $this->connection = 'mysql_connection_a'; 
     }else{ 
      $this->connection = 'sqlite_testing'; 
     } 
    } 
} 

如果你在測試中使用遷移我也有做類似在遷移文件中使用方法,併爲每個連接使用特徵。

爲我創造一個特質,看起來低於喜歡的mysql_connection_a覆蓋getConnection方法:

trait ConnectionAConnectionTrait 
{ 
    /** 
    * Get the migration connection name. 
    * 
    * @return string 
    */ 
    public function getConnection() 
    { 
     if (env('APP_ENV') != 'testing') { 
      return 'mysql_connection_a'; 
     } 
     return 'sqlite_testing'; 
    } 
} 

然後在遷移它看起來像這樣

use Database\migrations\traits\ConnectionAConnectionTrait; 

class CreateUsersTable extends Migration { 

    use ConnectionAConnectionTrait; 

    /** 
    * Run the migrations. 
    * 
    * @return void 
    */ 
    public function up() 
    { 
     Schema::connection($this->getConnection()) 
      ->create('users', function(Blueprint $table) 
      { 
+1

最好不要使用'env()'輔助函數,b/c會使配置緩存[[reference](https://laravel.com/docs/5.4/configuration#configuration-caching)]失效。相反,你可以使用'config('app.env')'。 – curtisblackwell