2013-12-11 43 views
4

我正在使用phpunit和嘲諷學習laravel中的單元測試。我目前正在測試UsersController :: store()。mockery-> shouldReceive()傳遞時它不應該?

我嘲笑用戶模型,並使用它來測試索引方法,似乎工作。當我拿出$ this-> user-> all()時,測試失敗,並且當它通過時。

雖然我正在使用模擬來測試用戶模型接收validate()一次,但測試存儲方法時。商店方法是空的,但測試通過。我已經離開了之類的無關緊要的部件着想brevities

<?php 

class UsersController extends BaseController { 

    public function __construct(User $user) 
    { 
     $this->user = $user; 
    } 
    /** 
    * Display a listing of the resource. 
    * 
    * @return Response 
    */ 
    public function index() 
    { 
     $users = $this->user->all(); 

     return View::make('users.index') 
     ->with('users', $users); 
    } 

    /** 
    * Show the form for creating a new resource. 
    * 
    * @return Response 
    */ 
    public function create() 
    { 
     return View::make('users.create'); 
    } 

    /** 
    * Store a newly created resource in storage. 
    * 
    * @return Response 
    */ 
    public function store() 
    { 
     // 
    } 

} 

UserControllerTest.php

<?php 
    use Mockery as m; 
class UserControllerTest extends TestCase { 

    public function __construct() 
    { 
     $this->mock = m::mock('BaseModel', 'User'); 
    } 

    public function tearDown() 
    { 
     m::close(); 
    } 

    public function testIndex() 
    { 
     $this->mock 
      ->shouldReceive('all') 
      ->once() 
      ->andReturn('All Users'); 
     $this->app->instance('User', $this->mock); 
     $this->call('GET', 'users'); 
     $this->assertViewHas('users', 'All Users'); 
    } 

    public function testCreate() 
    { 
     View::shouldReceive('make')->once(); 
     $this->call('GET', 'users/create'); 
     $this->assertResponseOk(); 
    } 

    public function testStore() 
    { 

     $this->mock 
      ->shouldReceive('validate') 
      ->once() 
      ->andReturn(m::mock(['passes' => 'true'])); 
     $this->app->instance('User', $this->mock); 
     $this->call('POST', 'users'); 
    } 


} 

回答

2

你不應該覆蓋的PHPUnit_Framework_TestCase構造,使用setUp初始化目的。另請參閱我的回答#15051271以及#17504870

+0

謝謝你,我認爲這有伎倆。至少testStore現在失敗了。但是,我的測試擴展了擴展phpunits測試用例的測試用例。 testcase有setUp(){parent :: setUp(); $ this-> prepareForTests();}所以在每個單獨的測試類中使用setUp會覆蓋這是我的權利?有另一種方法嗎?我只是在每個測試函數中創建一個模擬對象,以使其工作。 – Ir1sh

+0

你的類中的setUp方法也需要調用parent :: setUp()。這應該是要走的路。 –

+0

現在全世界似乎都很好謝謝 – Ir1sh

12

嘲弄缺省爲存根庫,而不是嘲諷一個(這是因爲它的名字的混淆)。

這意味着->shouldReceive(...)默認爲「零次或多次」。當使用->once()時,你說它應該被稱爲零次或一次,但不會更多。這意味着它會一直通過。

當你要斷言它被調用一次,你可以使用->atLeast()->times(1)(一次或多次)或->times(1)(正好一次)

+0

感謝您的快速回復。那麼爲什麼testIndex失敗,如果我刪除索引()中的所有調用?在兩次測試中,我只換了一次()一次(1),仍然得到了同樣的結果。當我在index()中刪除對all()的調用時,testIndex失敗。在testindex無風雨天氣我使用一次()或次(1)從嘲笑invalidcountexception說all()應該被稱爲1次,但被稱爲0times。 – Ir1sh

+1

「 - > shouldReceive(...)」只在默認情況下等於「零次或多次」,不會影響其他方法。 「 - > once()」表明它應該被調用一次,如果你不叫它,它就會失敗。 – Cmorales

3

要完成Wounter's answer,必須致電Mockery::close()

該靜態調用清理當前測試使用的Mockery容器,並運行您期望所需的任何驗證任務。

This答案幫助我理解了這個概念。

+1

你救了我的命,謝謝。 – vjarysta