Laravel & amp; Издевательство: модульное тестирование метода обновления без попадания в базу данных

Хорошо, так что я довольно новичок в юнит-тестировании, издевательстве и метании. Я пытаюсь провести модульное тестирование моего контроллера ресурсов, но я застрял в функции обновления. Не уверен, что делаю что-то не так или просто ошибаюсь.

Вот мой контроллер:

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,

Я достаточно ясно? Дай мне знать иначе. Спасибо!

3

Решение

Попробуйте издеваться findOrFail метод не вернуть new Book, но вместо этого вернуть фиктивный объект, у которого есть метод обновления.

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

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector