2014-11-03 19 views
8

我有一些像在Laravel以下設置:Laravel框架類PHPUnit中的數據提供不可

/app/controllers/MyController.php

class MyController extends BaseController { 

    const MAX_FILE_SIZE = 10000; 

    // .... 

} 

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

但是,當我運行vendor/bin/phpunit我ge噸以下錯誤:

 
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 

如果刪除在myDataProvider()的參考MyController類並用常量替換它,然後測試成功完成。

另外,我可以在實際的testMyController()方法內放置對MyController::MAX_FILE_SIZE的引用,並且測試也成功完成。

看來,對於Laravel框架類的自動加載設置沒有被設置到之後被調用數據提供方法,但之前實際的測試方法被調用。 有沒有辦法解決這個問題,以便我可以從PHPUnit數據提供者中訪問Laravel框架類?


注:我直接從命令行而不是從呼叫PHPUnit的一個IDE內(如NetBeans的)。我知道有些人有問題,但我認爲這不適用於我的問題。

回答

11

正如暗示在this answer中,這似乎與PHPUnit在任何測試用例中調用任何數據提供者和setUp()方法的順序有關。

PHPUnit將在之前調用數據提供者方法運行任何測試。在每次測試之前,它還會在測試用例中調用setUp()方法。 Laravel鉤入setUp()方法,調用$this->createApplication(),它將控制器類添加到「包含路徑」,以便它們可以正確自動加載。

由於數據提供者方法在發生這種情況之前運行,因此對數據提供者內部控制器類的任何引用都會失敗。這是可能的變通解決此通過修改測試類是這樣的:

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

這將調用createApplication()數據提供方法之前運行,所以有一個有效的應用實例,讓適當的類是自動加載正確。

這似乎工作,但我不知道這是最好的解決方案,或者如果它可能會導致任何問題(雖然我想不出爲什麼它應該)。

+2

調用'$ this-> refreshApplication();'可能會更安全,因爲這也會將環境設置爲'testing'。你也不一定需要創建一個構造函數,你可以直接在數據提供者中調用'$ this-> refreshApplication();'(如果你只有一個我猜的)。 – Antonio 2017-07-13 10:38:58

4

如果您在dataProvider方法內創建應用程序,測試的初始化速度會快得多,尤其是如果您有大量要測試的項目時。

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

    return [ 
     [ MyController::MAX_FILE_SIZE ] 
    ]; 
}