2016-04-24 96 views
0

一直在尋找所有在互聯網上,但似乎還沒有找到解決我的問題。我一直在使用PHPUnit和Mockery進入Laravel測試控制器。但是,我似乎並沒有讓我基於雄辯的模型正確地被嘲笑。我確實設法以相同的方式嘲弄我的Auth :: user(),雖然這在下面的測試中沒有使用。在AddressControllerLaravel 5 - 用嘲弄嘲弄雄辯模型

功能需要被測試:

public function edit($id) 
{ 
    $user = Auth::user(); 
    $company = Company::where('kvk', $user->kvk)->first(); 
    $address = Address::whereId($id)->first(); 

    if(is_null($address)) { 
     return abort(404); 
    } 

    return view('pages.address.update') 
     ->with(compact('address')); 
} 

含有延伸ControllerTest

class AddressControllerTest extends ControllerTest 
{ 
    /** 
    * @var \App\Models\Address 
    */ 
    private $_address; 

    /** 
    * @var \App\Http\Controllers\AddressController 
    */ 
    protected $_controller; 

    public function setUp(){ 
     parent::setUp(); 
     $this->_controller = new AddressController(); 
     $this->_address = factory(Address::class)->make(); 
    } 

    public function testEdit404(){ 
     $companyMock = $this->mock(Company::class); 
     $companyMock 
      ->shouldReceive('where') 
      ->with('kvk', Mockery::any()) 
      ->once(); 
      ->andReturn(factory(Company::class)->make([ 
       'address_id' => $this->_address->id 
      ])); 

     $addressMock = $this->mock(Address::class); 
     $addressMock 
      ->shouldReceive('whereId') 
      ->with($this->_address->id) 
      ->once(); 
      ->andReturn(null); 

     //First try to go to route with non existing address 
     $this->action('GET', '[email protected]edit', ['id' => $this->_address->id]); 
     $this->assertResponseStatus(404); 
    } 
} 

它保持投擲是該錯誤安裝程序和模擬方法

abstract class ControllerTest extends TestCase 
{ 
    /** 
    * @var \App\Http\Controllers\Controller 
    */ 
    protected $_controller; 

    public function setUp(){ 
     parent::setUp(); 
     $this->createApplication(); 
    } 

    public function tearDown() 
    { 
     parent::tearDown(); 
     Mockery::close(); 
    } 

    protected function mock($class) 
    { 
     $mock = Mockery::mock($class); 
     $this->app->instance($class, $mock); 
     return $mock; 
    } 
} 

AddressControllerTest ControllerTest:

1) AddressControllerTest::testEdit404 
Mockery\Exception\InvalidCountException: Method where("kvk", object(Mockery\Matcher\Any)) from Mockery_1_Genta_Models_Company should be called exactly 1 times but called 0 times. 

也許任何人有一個想法?

+0

,同時檢查,如果我的控制器的方法得到了所有調用,它置換後的確與$這個 - >行動()方法取代了$這個 - >()方法調用。但問題依然存在。 –

回答

5

好吧,由Jeffrey路(後面Laracasts的傢伙)發現多個帖子,建議人們停止嘲笑雄辯對象和內存數據庫,而不是使用我試過這種方法之後。我認爲這對未來有相同問題的其他用戶可能非常有用,所以我會在下面解釋。

現在我已經編輯了我的「的config/database.php中」文件,以支持內存數據庫選項使用SQLite:

'sqlite' => [ 
      'driver' => 'sqlite', 
      'database' => ':memory:', 
      'prefix' => '', 
     ], 

接下來你會看到下面的配置文件的頂部:

'default' => env('DB_CONNECTION', 'mysql'), 

這可以保持不變,這意味着Laravel將檢查您的.ENV變量來找到一個「DB_CONNECTION」或者使用MySQL作爲默認。這可能是您像平常一樣運行應用程序時要執行的操作。但是,通過測試,您希望覆蓋此配置,並將數據庫配置臨時設置爲'sqlite'。這可以通過添加「DB_CONNECTION」變量設置爲.ENV文件來完成:

DB_CONNECTION=mysql 

最後,在你的phpunit.xml,使用Laravel到instantiatie單元測試配置文件,你一定要告訴,當測試這個變量應設置爲「源碼」:

<env name="DB_CONNECTION" value="sqlite"/> 

現在你完成和Laravel將啓動一個無形的內存數據庫每次你即將去測試。不要忘記將以下行添加到需要數據庫的測試中。

use \Illuminate\Foundation\Testing\DatabaseMigrations; 

它會告訴Laravel在開始測試之前運行數據庫遷移,因此您可以像平常一樣使用表格。

這樣,它完全適用於我!希望你們可以使用它。

+0

適合我。謝謝。遷移後我也播種了數據庫。只是一個警告:你會發現'@depends testCreateCard' notation可以讓我們說一個從方法到方法的ID,因爲'setUp()'每次測試運行一次,每次DB都會被重置。我解決了播種我的數據並使用硬編碼值。 – mayid