PHPUnit: ожидаемый код состояния 200, но получено 419 с Laravel

PHPUnit: ожидаемый код состояния 200, но получено 419 с Laravel

20.09.2017 06:12:47 Просмотров 52 Источник

Я хочу протестировать метод delete, но я не получаю ожидаемых результатов от PHPUnit. Я получаю это сообщение при выполнении теста:

 Expected status code 200 but received 419. Failed asserting that false is true.
 /vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestResponse.php:77
 /tests/Unit/CategoriesControllerTest.php:70

Версия Laravel: 5.5

Спасибо за любую помощь!

Конструктор контроллера:

public function __construct()
{
    $this->middleware('auth');

    $this->middleware('categoryAccess')->except([
        'index',
        'create'
    ]);
}

Способ управления:

public function destroy($categoryId)
{
    Category::destroy($categoryId);

    session()->flash('alert-success', 'Category was successfully deleted.');

    return redirect()->action('CategoriesController@index');
}

categoryAccess промежуточного:

public function handle($request, Closure $next)
{
    $category = Category::find($request->id);

    if (!($category->user_id == Auth::id())) {
        abort(404);
    }

    return $next($request);
}

Категория модель:

protected $dispatchesEvents = [
    'deleted' => CategoryDeleted::class,
];

Слушатель события

public function handle(ExpensesUpdated $event)
{
    $category_id = $event->expense->category_id;

    if (Category::find($category_id)) {
        $costs = Category::find($category_id)->expense->sum('cost');

        $category = Category::find($category_id);

        $category->total = $costs;

        $category->save();
    }
}

PHPUnit удалить тест:

use RefreshDatabase;

protected $user;

public function setUp()
{
   parent::setUp();
   $this->user = factory(User::class)->create();
   $this->actingAs($this->user);
}

/** @test */
public function user_can_destroy()
{
    $category = factory(Category::class)->create([
        'user_id' => $this->user->id
    ]);

    $response = $this->delete('/category/' . $category->id);

    $response->assertStatus(200);

    $response->assertViewIs('category.index');
}
У вопроса есть решение - Посмотреть?

https://stackoverflow.com/questions/46325790/phpunit-expected-status-code-200-but-received-419-with-laravel#comment79612741_46325790
Привет, спасибо, я добавил Это в метод и снова запустил тест, и теперь я получаю это сообщение: ожидаемый код состояния 200, но получил 302.
https://stackoverflow.com/questions/46325790/phpunit-expected-status-code-200-but-received-419-with-laravel#comment79613801_46325790
Спасибо @Maraboc $this - >withoutMiddleware (); работает! Дело в том, что этот тест должен ожидать код состояния 302, который я узнал, прочитав ответ отсюда .
https://stackoverflow.com/questions/46325790/phpunit-expected-status-code-200-but-received-419-with-laravel#comment79614007_46325790
Это хорошо знать. ;)

Ответы - PHPUnit: ожидаемый код состояния 200, но получено 419 с Laravel / PHPUnit: Expected status code 200 but received 419 with Laravel

Является ответом!
Maraboc

20.09.2017 06:57:19

Иногда при тестировании вам нужно будет отключить промежуточные программы, чтобы продолжить :

use Illuminate\Foundation\Testing\WithoutMiddleware;

class ClassTest extends TestCase
{
    use WithoutMiddleware; // use this trait

    //tests here
}

и если вы хотите отключить их только для одного конкретного теста используйте :

$this->withoutMiddleware();
https://stackoverflow.com/questions/46325790/phpunit-expected-status-code-200-but-received-419-with-laravel/46326721#comment97445385_46326721
Это работает, за исключением случаев, когда промежуточное программное обеспечение фактически является частью ваших тестов.
piscator

16.01.2018 03:41:27

Решение: при кэшировании файлов конфигурации вы можете решить эту проблему, запустив php artisan config:clear.

Объяснение: причина, по которой это может решить проблему, заключается в том, что PHPUnit будет использовать кэшированные значения конфигурации вместо переменных, определенных в тестовой среде. В результате APP_ENVне настроен на тестирование, и VerifyCsrfTokenMiddlewareвыдаст исключение TokenMismatchException(код состояния 419).

Он не будет выдавать это исключение, когда APP_ENVнастроен на тестирование, так как метод дескриптора VerifyCsrfTokenMiddlewareпроверяет, выполняются ли модульные тесты с VerifyCsrfTokenMiddleware.

Рекомендуется не кэшировать конфигурацию в среде разработки. Если вам нужно кэшировать конфигурацию в среде, где также выполняются модульные тесты, вы можете очистить кэш вручную в своем $this->runningUnitTests():

TestCase.php

Пример на основе https://github.com/laravel/framework/issues/13374#issuecomment-239600163

https://stackoverflow.com/questions/46325790/phpunit-expected-status-code-200-but-received-419-with-laravel/48281547#comment101746141_48281547
Это сработало и для меня, но почему это решает проблему?
https://stackoverflow.com/questions/46325790/phpunit-expected-status-code-200-but-received-419-with-laravel/48281547#comment101759011_48281547
@DarrenFindlay я добавил некоторые пояснения.
Hussam

26.05.2018 07:37:52

измените файл app/Http/Middleware/VerifyCsrfToken.phpпутем добавления:

public function handle($request, \Closure $next)
{
    if ('testing' !== app()->environment())
    {
        return parent::handle($request, $next);
    }

    return $next($request);
}

источник: https://laracasts.com/discuss/channels/testing/trouble-testing-http-verbs-with-phpunit-in-laravel/replies/29878

Jouva Moufette

27.05.2019 10:13:58

Сообщение здесь действительно связано с промежуточным программным обеспечением CSRF. Но есть гораздо лучший способ борьбы с этой проблемой, чем отключение промежуточного программного обеспечения.

Промежуточное ПО поставляется со встроенным кодом, который определяет, используется ли оно в тесте. Этот чек ищет 2 вещи:

  • Я управляюсь через командную строку
  • Выполняется ли я в среде типа testing

По умолчанию, правильная настройка программного обеспечения правильно приводит к тому, что оба флага будут истинными при запуске PHP unit. Однако наиболее вероятным виновником является значение в вашем APP_ENV. Общие способы для этого, чтобы быть неправильным включают в себя:

  • Неправильно phpunit.xml-файл. Он должен содержать <server name="APP_ENV" value="testing" />
  • Сеанс оболочки, имеющий явное значение, установленное в APP_ENVкоторое переопределяет это значение
  • Сеанс Docker / docker-compose/kubernetes, имеющий явное значение, установленное в APP_ENV. Видя о получении этого значения, установленного через .env и / или phpunit.xml-файлы, возможно, лучше, если это возможно. Или обеспечение процесса сборки/тестирования, задающего значение.

Это тоже поставило меня в тупик, и я не был уверен, что мне понадобится использование WithoutMiddleware, поскольку я не делал этого для другого проекта, но оказалось, что я экспериментировал с чем-то в командной строке и переиграл APP_ENVв bash.

Farid shahidi

16.12.2019 11:23:30

Это точное решение.:

Среда Laravel будет установлена после начальной загрузки приложения, поэтому вы не можете изменить ее из appServiceProvider или другого источника. для исправления этой ошибки необходимо добавить эту функцию в App\Http\Middleware\VerifyCsrfToken

public function handle($request, \Closure $next)
    {
        if(env('APP_ENV') !== 'testing')
        {
            return parent::handle($request, $next);
        }

        return $next($request);
    }

вам нужно использовать env ('APP_ENV'), который установлен.ОКР.файл тестирования с

APP_ENV=testing
Помочь в развитии проекта:
Закрыть X