2017-06-06 26 views
3

私は複数のデータベースアクセスでアプリケーションを開発しており、これでPHPUnitテストを行いたいと思います。私の現在のアプローチは、config\databases.phpの複数の接続(mysql、mysql2、mysql3)を持つことで、envファイルにすべてのアクセスを持つことができます。このため、モデルには$connection変数が定義されています。私の最初の機能テストでは、ページにアクセスして、自分の工場で提供しているデータを参照したいので、開始するだけです。私のphpunit.xmlファイルではをsqliteと指定し、それぞれのMySql設定にはvalue=":memory:"を設定しました。Laravel複数のデータベースPHPUnit

LATER EDITだから上記

<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で

私はこのコードの私のconfig/database.phpでファイルで

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

を持って、私はデータベースごとに設定さコネクションを持っている、と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, 
    ], 

次に、各接続の特性を作成して接続を設定し、関連するモデルに組み込みます。例えばUserモデルはmysql_connection_aを使用するために必要な場合、私は、形質が、この

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'; 
     } 
    } 
} 

ようになり、あなたのテストでの移行を使用している場合、私はまた、同様の操作を行う必要がありました

use App\Traits\ConnectionATrait; 

class User extends Authenticatable 
{ 
    use Notifiable, ConnectionATrait; 

モデルでConnectionATraitを使用しますアプローチを使用して、接続ごとに特性を使用します。私はそれ以下の同類は、getConnectionメソッドをオーバーライドするに見える形質を作成mysql_connection_aするため

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()'ヘルパーを使わないほうが良いでしょう。それはconfigキャッシュ[[reference](https://laravel.com/docs/5.4/configuration#configuration-caching)]を破ってしまいます。代わりに 'config( 'app.env')'を使うことができます。 – curtisblackwell

関連する問題