Laravel 4.2: тестирование с assertRedirectedToRoute завершается неудачно

Мне было интересно, сталкивался ли кто-нибудь еще с этой проблемой. Я просматриваю книгу Джеффри Уэя по тестированию в Laravel, и я в главе, которая объясняет, как тестировать контроллеры.

Когда я следую примерам из книги — я получаю сообщение:

Не удалось утверждать, что объект Illuminate \ Http \ Response (…) является
экземпляр класса «Illuminate \ Http \ RedirectResponse».

Мой тест выглядит следующим образом:

public function testStoreFails()
{

$input = ['title' => ''];

$this->mock
->shouldReceive('create')
->once()
->with($input);

$this->app->instance('Post', $this->mock);

$this->post('posts', $input);

$this->assertRedirectedToRoute('posts.create');

$this->assertSessionHasErrors(['title']);

}

И очень простой метод в контроллере (просто для проверки этого конкретного сценария):

public function create()
{

$input = Input::all();

$validator = Validator::make($input, ['title' => 'required']);

if ($validator->fails()) {

return Redirect::route('posts.create')
->withInput()
->withErrors($validator->messages());

}

$this->post->create($input);

return Redirect::route('posts.index')
->with('flash', 'Your post has been created!');

}

Из того, что я вижу AssertionsTrait::assertRedirectedTo проверяет, например, Illuminate\Http\RedirectResponse

/**
* Assert whether the client was redirected to a given URI.
*
* @param  string  $uri
* @param  array   $with
* @return void
*/
public function assertRedirectedTo($uri, $with = array())
{
$response = $this->client->getResponse();

$this->assertInstanceOf('Illuminate\Http\RedirectResponse', $response);

$this->assertEquals($this->app['url']->to($uri), $response->headers->get('Location'));

$this->assertSessionHasAll($with);
}

/**
* Assert whether the client was redirected to a given route.
*
* @param  string  $name
* @param  array   $parameters
* @param  array   $with
* @return void
*/
public function assertRedirectedToRoute($name, $parameters = array(), $with = array())
{
$this->assertRedirectedTo($this->app['url']->route($name, $parameters), $with);
}

который должен работать очень хорошо, так как фасад Redirect разрешается в Illuminate\Routing\Redirector И его route() вызовы методов createRedirect(), который возвращает экземпляр Illuminate\Http\RedirectResponse — так что не совсем уверен, что это вызывает.

ОБНОВИТЬ:

Просто проверил код еще раз, и похоже, что проблема в AssertionsTrait::assertRedirectedTo() метод. Призыв к $this->client->getResponse() возвращает экземпляр Illuminate\Http\Response вместо Illuminate\Http\RedirectResponse — следовательно $this->assertInstanceOf('Illuminate\Http\RedirectResponse', $response) вызов не проходит. Но я все еще не уверен, почему — я расширяю TestCase который должен позаботиться обо всех настройках среды и т. д. Есть идеи?

1

Решение

Публикация комментария как ответа:

Поскольку вы работаете с находчивым объектом, Laravel автоматически создает для вас несколько маршрутов, а именно:

+-----------------------------+---------------+-------------------------+
| URI                         | Name          | Action                  |
+-----------------------------+---------------+-------------------------+
| GET|HEAD posts              | posts.index   | PostsController@index   |
| GET|HEAD posts/create       | posts.create  | PostsController@create  |
| POST posts                  | posts.store   | PostsController@store   |
| GET|HEAD posts/{posts}      | posts.show    | PostsController@show    |
| GET|HEAD posts/{posts}/edit | posts.edit    | PostsController@edit    |
| PUT posts/{posts}           | posts.update  | PostsController@update  |
| PATCH posts/{posts}         |               | PostsController@update  |
| DELETE posts/{posts}        | posts.destroy | PostsController@destroy |
+-----------------------------+---------------+-------------------------+

Как вы можете видеть, POST-запрос к / posts (как вы это делаете в своем тесте) вызывает store() метод на вашем PostsController, а не create() метод, который вы предполагали проверить.

create а также store так же как edit а также update может иногда сбивать с толку. Вот разница:

  • create() — показать форму для создания нового ресурса
  • store() — фактически создать ресурс из размещенных данных

  • edit($id) — показать форму для редактирования указанного ресурса
  • update($id) — фактически обновить ресурс с опубликованными данными
1

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

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

По вопросам рекламы [email protected]