2014-11-03 19 views
8

Tôi có dạng như sau thành lập năm Laravel:lớp khung Laravel không có sẵn trong cung cấp dữ liệu PHPUnit

Trong /app/controllers/MyController.php:

class MyController extends BaseController { 

    const MAX_FILE_SIZE = 10000; 

    // .... 

} 

Trong /app/tests/MyControllerTest.php:

class MyControllerTest extends TestCase { 

    public function myDataProvider() { 
     return [ 
      [ MyController::MAX_FILE_SIZE ] 
     ]; 
    } 

    /** 
    * @dataProvider myDataProvider 
    */ 
    public function testMyController($a) { 
     // Just an example 
     $this->assertTrue(1 == 1); 
    } 
} 

Tuy nhiên, khi tôi chạy vendor/bin/phpunit Tôi ge t các lỗi sau:

 
PHP Fatal error: Class 'Controller' not found in /home/me/my-app/app/controllers/BaseController.php on line 3 

Fatal error: Class 'Controller' not found in /home/me/my-app/app/controllers/BaseController.php on line 3 

Nếu tôi loại bỏ các tham chiếu đến lớp MyController trong myDataProvider() và thay thế bằng một hằng số đen thì kiểm tra hoàn tất thành công.

Ngoài ra, tôi có thể đặt tham chiếu đến MyController::MAX_FILE_SIZE bên trong phương thức testMyController() thực tế và thử nghiệm cũng hoàn tất thành công.

Dường như các thiết lập tự động load cho các lớp khuôn khổ Laravel không được thiết lập cho đến khi sau phương pháp cung cấp dịch vụ dữ liệu đang được gọi, nhưng trước các phương pháp thử nghiệm thực tế được gọi là. Có cách nào xung quanh điều này để tôi có thể truy cập các lớp khung của Laravel từ bên trong một nhà cung cấp dữ liệu PHPUnit không?


LƯU Ý: Tôi gọi PHPUnit trực tiếp từ dòng lệnh và không phải từ bên trong một IDE (như NetBeans). Tôi biết một số người đã có vấn đề với điều đó, nhưng tôi không nghĩ rằng áp dụng cho vấn đề của tôi.

Trả lời

11

Như ngụ ý trong this answer, điều này dường như liên quan đến thứ tự mà PHPUnit sẽ gọi cho bất kỳ nhà cung cấp dữ liệu nào và phương thức setUp() trong mọi trường hợp thử nghiệm.

PHPUnit sẽ gọi phương thức nhà cung cấp dữ liệu trước khi chạy bất kỳ thử nghiệm nào. Trước mỗi bài kiểm tra, nó cũng sẽ gọi phương thức setUp() trong trường hợp kiểm tra. Laravel móc vào phương thức setUp() để gọi $this->createApplication() sẽ thêm các lớp điều khiển vào 'đường dẫn bao gồm' để chúng có thể được tự động tải một cách chính xác.

Vì các phương thức cung cấp dữ liệu được chạy trước khi điều này xảy ra, nên mọi tham chiếu đến các lớp điều khiển bên trong nhà cung cấp dữ liệu đều không thành công. Đó là công việc tốt này bằng cách thay đổi các lớp thử nghiệm một cái gì đó như thế này:

class MyControllerTest extends TestCase { 

    public function __construct($name = null, array $data = array(), $dataName = '') { 
     parent::__construct($name, $data, $dataName); 

     $this->createApplication(); 
    } 

    public function myDataProvider() { 
     return [ 
      [ MyController::MAX_FILE_SIZE ] 
     ]; 
    } 

    /** 
    * @dataProvider myDataProvider 
    */ 
    public function testMyController($a) { 
     // Just an example 
     $this->assertTrue(1 == 1); 
    } 
} 

này sẽ gọi createApplication() trước khi các phương pháp cung cấp dữ liệu đang chạy, và do đó là một trường hợp đơn hợp lệ mà sẽ cho phép các lớp học phù hợp để được tự động tải đúng.

Điều này có vẻ hiệu quả, nhưng tôi không chắc đó có phải là giải pháp tốt nhất hay không hoặc có thể gây ra bất kỳ sự cố nào (mặc dù tôi không thể nghĩ ra bất kỳ lý do gì nên làm).

+2

Có thể an toàn hơn khi gọi '$ this-> refreshApplication();', vì điều này cũng đặt môi trường thành 'testing'. Bạn cũng không nhất thiết phải tạo một hàm tạo, bạn chỉ có thể gọi '$ this-> refreshApplication();' trực tiếp trong nhà cung cấp dữ liệu của bạn (nếu bạn chỉ có một người tôi đoán). – Antonio

4

Thử nghiệm sẽ khởi chạy nhanh hơn nhiều nếu bạn tạo ứng dụng ngay trong phương thức dataProvider, đặc biệt nếu bạn có nhiều mục cần kiểm tra.

public function myDataProvider() { 
    $this->createApplication(); 

    return [ 
     [ MyController::MAX_FILE_SIZE ] 
    ]; 
} 
Các vấn đề liên quan