2017-04-18 31 views
7

Tôi có ứng dụng Laravel 5.4 có các mô hình trỏ đến các kết nối cơ sở dữ liệu khác nhau.Laravel 5: Xử lý nhiều kết nối và thử nghiệm

Ví dụ: tôi có User trỏ đến cơ sở dữ liệu MySQL và sau đó Company trỏ tới cơ sở dữ liệu PostgreSQL (sử dụng biến số $connection).

Bây giờ, khi tôi chạy PHPUnit tôi muốn biến $connection được thay thế bằng những gì được chỉ định trong tệp phpunit.xml, là một SQLite trong loại bộ nhớ cơ sở dữ liệu.

Làm cách nào để đạt được điều đó?

+0

tại sao câu trả lời được đưa ra không tốt cho vấn đề của bạn? – mimo

Trả lời

3

Off đỉnh đầu của tôi bạn có thể di chuyển các tên kết nối đến tập tin .env

trong mô hình của bạn:

public function __construct(array $attributes = []) 
{ 
    $this->connection = env('MY_CONNECTION'); 
    parent::__construct($attributes); 
} 

trong tập tin .env bạn

MY_CONNECTION=mysql 

trong phpunit .xml

<env name="MY_CONNECTION" value="sqlite"/> 
+1

bạn không phải di chuyển tất cả chuỗi kết nối đến tệp '.env'. Kiểm tra tốt hơn nếu một 'MY_CONNECTION' tồn tại. Nếu có, bạn có thể ghi đè lên biến kết nối. – mimo

0

Giống như Arturo Rojas đã viết trong câu trả lời của mình, bạn phải kiểm tra trong các nhà xây dựng, nếu biến kết nối phải được ghi đè:

public function __construct(array $attributes = []) 
{ 
    if(App::environment() == 'testing') { 
     $this->connection = env('DB_CONNECTION'); 
    } 
    parent::__construct($attributes); 
} 

Trong phpunit.xml của bạn, bạn cần những biến (DB_DATABASE là không bắt buộc):

<php> 
    <env name="APP_ENV" value="testing"/> 
    <env name="DB_CONNECTION" value="sqlite"/> 
    <env name="DB_DATABASE" value="testDatabase"/> 
<php> 

Laravel sau đó sẽ sử dụng kết nối sqllite từ /config/database.php

0

tôi không muốn chạm vào mã sản xuất và thay vào đó sử dụng container dịch vụ để tạo ra các dịch vụ kiểm tra cụ thể.

Trong trường hợp này, nếu bạn muốn tất cả các mẫu của bạn để sử dụng cùng một kết nối thử nghiệm mặc định:

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

(Đây đè CreatesApplication đặc điểm, bạn có thể thay vì đặt mã này bất cứ nơi nào giữa khi ứng dụng được bootstrapped và khi lệnh di chuyển được gọi).

(Cũng lưu ý rằng điều này đang sử dụng các lớp ẩn danh nội dòng PHP 7. Bạn cũng có thể xác định trình quản lý db giả làm lớp riêng).

0

Như đã đề cập trước đó, trước tiên bạn cần đặt kết nối trong mỗi Mô hình. Vì vậy, bạn thiết lập các kết nối trong tệp cấu hình cơ sở dữ liệu, đặt các giá trị trong tệp .env và sử dụng chúng trong các hàm tạo của Mô hình.

Để thử nghiệm, bạn cũng có thể thực hiện việc này. Thêm kết nối thử nghiệm vào tệp config/database.php và sau đó sử dụng tệp env ghi đè.

Tạo tệp env bổ sung, đặt tên cho nó là .env.testing.

Vì vậy, trong tập tin .env của bạn, bạn sẽ có:

CONNECTION_MYSQL=mysql 
CONNECTION_POSTGRESS=postgress 

Sau đó, trong tập tin .env.testing bạn có thể có:

CONNECTION_MYSQL=test_sqlite 
CONNECTION_POSTGRESS=test_sqlite 

Cuối cùng để tải tập tin env này khi thử nghiệm, đi đến CreatesApplication đặc điểm và cập nhật những nội dung sau:

public function createApplication() 
{ 
    $app = require __DIR__.'/../bootstrap/app.php'; 

    $app->loadEnvironmentFrom('.env.testing'); 

    $app->make(Kernel::class)->bootstrap(); 

    return $app; 
} 

Bằng cách sử dụng phương pháp loadEnvironemtFrom(), tất cả các thử nghiệm sử dụng đặc điểm này sẽ tải tệp .env.testing và sử dụng các kết nối được xác định tại đó.

Các vấn đề liên quan