2017-06-06 3 views
3

Ich entwickle eine Anwendung mit mehreren Datenbankzugriff und ich möchte PHPUnit Tests mit diesem haben. Mein aktueller Ansatz ist es, in der config\databases.php mehrere Verbindungen (mysql, mysql2, mysql3) zu haben, so dass ich in der env-Datei einen anderen Zugriff für alle von ihnen haben kann. Aus diesem Grund haben die Modelle die Variable $connection definiert. In meinem ersten Funktionstest möchte ich auf eine Seite zugreifen und nur die Daten sehen, die ich in meiner Fabrik zur Verfügung stelle, um die Dinge zu starten. In meiner phpunit.xml Datei habe ich die DB_CONNECTION als sqlite und für jede der MySql Einstellung die value=":memory:" haben.Laravel mehrere Datenbanken PHPUnit

SPÄTER 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> 

So oben Sie den entsprechenden Code von PHPUnit finden.

.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 

Das Problem, das ich habe, ist die Tatsache, dass, wenn ich die Tests ausführen, ich diesen Fehler haben ->PDOException: SQLSTATE[HY000] [1049] Unknown database ':memory:'.

Also irgendwie Laravel analysiert nicht den Speicherwert. Jeder Vorschlag wird geschätzt. Vielen Dank

+0

Was meinst du damit Sie jedes der mysql müssen Werteinstellung =: Speicher :? – Devon

+0

Könnten Sie bitte einen relevanten Code (Tests und Configs) posten? –

+0

Sie müssen Ihre Datenbankkonfigurationsdatei posten, da ich davon ausgehe, dass Sie größere Änderungen vorgenommen haben, wenn Sie 'DB_DATABASE_1',' DB_DATABASE_2' und 'DB_DATABASE_3' anstelle von' DB_DATABASE' verwenden. – Devon

Antwort

2

Ich hatte das gleiche Problem

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

Dann in der Migration:

Für die mysql_connection_a ich eine Eigenschaft erstellen, die gerne unter dem überschreibt die Methode getConnection sieht , aber ich habe Dinge mit einigen help from Adam Wathan on Twitter arbeiten.

Hier ist, was ich getan habe:

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= 

Stellen Sie sicher, dass auch für alle Benutzer, die nicht der PDOException entsprechen, die Verbindungen in Ihren Migrationen/Modellen festgelegt werden.

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

Schwer zu decodieren, wo Sie tatsächlich den Wert :memory: setzen.

Im phpunit.xml <php> Abschnitt soll dies ausreichend sein (vorausgesetzt, Sie nicht die SQLite-Verbindung geändert haben):

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

ein ähnliches Problem zu beheben, habe ich einen Zug auf den Modellklassen.

In meinem phpunit.xml habe ich diesen Code

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

In meiner config/database.php Datei-I-Verbindungen für jede der Datenbanken eingerichtet haben, und eine sqlite_testing Verbindung aufgebaut zum Testen

'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, 
    ], 

Ich erstelle dann ein Merkmal für jede meiner Verbindungen, um die Verbindung zu setzen und sie in die entsprechenden Modelle aufzunehmen. z.B. wenn die User-Modell mysql_connection_a verwenden benötigt würde ich ConnectionATrait im Modell verwendet

use App\Traits\ConnectionATrait; 

class User extends Authenticatable 
{ 
    use Notifiable, ConnectionATrait; 

Das Merkmal dann wie diese

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

aussehen würde, wenn Sie Migrationen in Ihren Tests verwenden musste ich auch ein ähnliches tun Vorgehensweise in den Migrationsdateien und verwenden Sie für jede Verbindung ein Merkmal.es würde so aussehen

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

Es ist besser, den 'env()' Helfer nicht zu verwenden, b/c zerbricht den Konfigurationscache [[Referenz] (https://laravel.com/docs/5.4/configuration#configuration-caching)]. Stattdessen können Sie 'config ('app.env')' verwenden. – curtisblackwell