2017-06-06 140 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