Одна из моих тестовых функций для модульного тестирования в Laravel продолжает выходить из строя. Я пытаюсь утверждать, что запрос конкретной страницы без выполнения определенных условий вызывает ошибку 403 FORBIDDEN.
Моя тестовая функция:
public function testNoAjaxCall() { $this->call('POST', 'xyz', array()); $this->assertResponseStatus(403); }
В действии контроллера это направлено, у меня есть:
if(!Input::has('ajax') || Input::get('ajax') != 1) { // Drop all 'non-ajax' requests. App::abort(403, 'Normal POST requests to this page are forbidden. Please explicitly tell me you\'re using AJAX by passing ajax = 1.'); }
Запуск phpunit возвращается со следующим:
1) RaceTest :: testNoAjaxCall
Symfony \ Component \ HttpKernel \ Exception \ HttpException: обычные POST-запросы на эту страницу запрещены. Пожалуйста, прямо скажите мне, что вы используете AJAX, передавая ajax = 1.
[Путь \ к \ Laravel] \ поставщика \ Laravel \ рамки \ SRC \ Осветите \ Foundation \ application.php: 875
[отредактированная трассировка стека]
[Путь \ к \ Laravel] \ поставщика \ Symfony \ HTTP-ядра \ Symfony \ Component \ HttpKernel \ Client.php: 81
[Путь \ к \ Laravel] \ поставщика \ Symfony \ браузер-набор \ Symfony \ Component \ BrowserKit \ Client.php: 325
[Путь \ к \ Laravel] \ поставщика \ Laravel \ рамки \ SRC \ Осветите \ Foundation \ Testing \ TestCase.php: 74
[Путь \ к \ Laravel] \ приложение \ тесты [testFileName] .php: 176
ОТКАЗЫ!
Тесты: 6, Утверждения: 17, Ошибки: 1.
Конечно, трассировка стека возвращается к $this->call(..);
и App::abort(..)
У меня есть обработчик ошибок HttpException в моем файле app/start/global.php
, который работает при запуске его за пределами модульного тестирования (например, запрос POST
непосредственно на тестируемый URL-адрес), но модульное тестирование, похоже, неправильно исключение или даже выйти на вызов assert.
Что мне не хватает?
http://phpunit.de/manual/3.7/en/appendixes.annotations.html#appendixes.annotations.expectedException должно уже объяснить это.
/** * @expectedException \Symfony\Component\HttpKernel\Exception\HttpException * @expectedExceptionMessage Normal POST requests to this page are forbidden. Please explicitly tell me you\'re using AJAX by passing ajax = 1. */ public function testNoAjaxCall() { $this->call('POST', 'xyz', array()); }
На данный момент лучший способ, который я нашел, чтобы утверждать коды статуса HttpException, можно найти в работе sirbarrence по адресу https://github.com/laravel/framework/issues/3979
TestCase.php:
public function assertHTTPExceptionStatus($expectedStatusCode, Closure $codeThatShouldThrow) { try { $codeThatShouldThrow($this); $this->assertFalse(true, "An HttpException should have been thrown by the provided Closure."); } catch (\Symfony\Component\HttpKernel\Exception\HttpException $e) { // assertResponseStatus() won't work because the response object is null $this->assertEquals( $expectedStatusCode, $e->getStatusCode(), sprintf("Expected an HTTP status of %d but got %d.", $expectedStatusCode, $e->getStatusCode()) ); } }
Применение:
public function testGetFailsWith403() { $this->assertHTTPExceptionStatus(403, function ($_this) { $_this->call('GET', '/thing-that-should-fail'); }); }