Хорошо, поэтому я довольно новичок как для модульного тестирования, издевательства, так и для laravel. Я пытаюсь выполнить тестирование моего контроллера ресурсов, но я застрял в функции обновления. Не уверен, что я делаю что-то неправильно или просто ошибаюсь.Laravel & Mockery: модуль тестирует метод обновления без попадания в базу данных
Вот мой контроллер:
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)
, это было бы неправильно издевательством, и база данных не была бы затронута, но при использовании функции из frontend она обновила бы все мои записи.
Думаю, я просто хочу знать, как насмехаться $book-object properly
.
Я достаточно ясно? Дайте мне знать иначе. Благодаря!
Сначала я думал, что ваш '$ this-> book' был [хранилище] (http://culttt.com/2013/07/08/creating-flexible-controllers-in-laravel-4- using-repositories /), но, глядя ближе, он больше похож на модель Eloquent. Это правильно? –
Правильно. Я думал об использовании репозиториев, но решил, что это вызовет у меня слишком много путаницы. – Mattias
Проблема в том, что это одна из основных причин, по которой люди используют репозитории: это делает тестирование намного проще. –