簡體   English   中英

Laravel&Mockery:單元測試更新方法而不需要訪問數據庫

[英]Laravel & Mockery: Unit testing the update method without hitting the database

好吧所以我對單元測試,嘲弄和laravel都很陌生。 我正在嘗試對我的資源控制器進行單元測試,但我仍然堅持更新功能。 不確定我做錯了什么或只是想錯了。

這是我的控制器:

class BooksController extends \BaseController {

    // Change template.
    protected $books;

    public function __construct(Book $books)
    {
        $this->books = $books;
    }

    /**
     * Store a newly created book in storage.
     *
     * @return Response
     */
    public function store()
    {
        $data       = Input::except(array('_token'));
        $validator  = Validator::make($data, Book::$rules);

        if($validator->fails())
        {
            return Redirect::route('books.create')
                ->withErrors($validator->errors())
                ->withInput();
        }

        $this->books->create($data);

        return Redirect::route('books.index');
    }

    /**
     * Update the specified book in storage.
     *
     * @param  int  $id
     * @return Response
     */
    public function update($id)
    {
        $book       = $this->books->findOrFail($id);
        $data       = Input::except(array('_token', '_method'));
        $validator = Validator::make($data, Book::$rules);

        if($validator->fails())
        {
            // Change template.
            return Redirect::route('books.edit', $id)->withErrors($validator->errors())->withInput();
        }

        $book->update($data);

        return Redirect::route('books.show', $id);
    }
}

這是我的測試:

public function testStore()
{
    // Add title to Input to pass validation.
    Input::replace(array('title' => 'asd', 'content' => ''));

    // Use the mock object to avoid database hitting.
    $this->mock
        ->shouldReceive('create')
        ->once()
        ->andReturn('truthy');

    // Pass along input to the store function.
    $this->action('POST', 'books.store', null, Input::all());

    $this->assertRedirectedTo('books');
}

public function testUpdate()
{
    Input::replace(array('title' => 'Test', 'content' => 'new content'));

    $this->mock->shouldReceive('findOrFail')->once()->andReturn(new Book());
    $this->mock->shouldReceive('update')->once()->andReturn('truthy');

    $this->action('PUT', 'books.update', 1, Input::all());      

    $this->assertRedirectedTo('books/1');
}

問題是,當我這樣做時,我得到Mockery\\Exception\\InvalidCountException: Method update() from Mockery_0_Book should be called exactly 1 times but called 0 times. 因為我的控制器中有$book->update($data) 如果我要將其更改為$this->books->update($data) ,它將被正確模擬並且不會觸及數據庫,但是當使用前端函數時它會更新我的所有記錄。

我想我只是想知道如何$book-object properly模擬$book-object properly

我清楚了嗎? 別的我知道。 謝謝!

嘗試findOrFail方法不返回new Book ,而是返回一個模擬對象,而不是它有一個更新方法。

$mockBook = Mockery::mock('Book[update]');
$mockBook->shouldReceive('update')->once();
$this->mock->shouldReceive('findOrFail')->once()->andReturn($mockBook);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM