为啥我在 laravel 中运行测试时收到“CSRF 令牌不匹配”?

Posted

技术标签:

【中文标题】为啥我在 laravel 中运行测试时收到“CSRF 令牌不匹配”?【英文标题】:Why I receive "CSRF token mismatch" while running tests in laravel?为什么我在 laravel 中运行测试时收到“CSRF 令牌不匹配”? 【发布时间】:2020-07-21 17:40:23 【问题描述】:

我想在不收到“CSRF 令牌不匹配”异常的情况下运行我的测试。在 laravel 文档中指出:

运行测试时自动禁用 CSRF 中间件。

抛出异常的代码行如下所示:

$response = $this->json('POST', route('order.create'), [
     'product_id', $product->id
]);

为了运行测试,我正在我的 zsh 终端中工作:

php artisan test --env=testing

这是我的测试课:

<?php

   namespace Tests\Feature;

   use Illuminate\Foundation\Testing\RefreshDatabase;
   use Illuminate\Foundation\Testing\WithFaker;
   use Illuminate\Foundation\Testing\WithoutMiddleware;
   use Tests\TestCase;

  class SessionCartTest extends TestCase
  
      public function testExample()
      
          $product = \App\Product::inRandomOrder()->first();
          $response = $this->postJson(route('order.insert'), [
              'product_id' => $product->id,
          ]);
          $response->assertStatus(200); // here I receive 419
      
  

我做错了什么,我该如何解决这个问题?我正在使用 laravel 7。

【问题讨论】:

为什么要使用 artisan 命令来运行测试?在控制台上运行 phpunit 会发生什么?你确定你得到了一个 CSRF 异常吗? 运行phpunit时也是一样。我正在转储响应,我看到里面有什么,HTTP 错误代码也是 419。 你能包含你的测试类吗? @DigitalDrifter 我在问题中添加了我的测试类 在 Illuminate\Foundation\Http\Middleware\VerifyCsrfToken 构造函数中以某种方式将 $app->env 设置为“本地”而不是“测试” 【参考方案1】:

我现在遇到这个问题 x 次,每次我通过运行来解决它: php artisan config:clear

【讨论】:

我需要做一个杯子,上面写着这个什么的。很多次我发现了一些非常奇怪的行为,这已经解决了。 发现了很多奇怪的行为。这救了我的OT。谢谢! 非常感谢。我看到全身都是红色,惊慌失措......【参考方案2】:

可能APP_ENV 未设置为testing

您可以在命令行中通过在 php 命令前面设置 ENV 变量。

因此,在您的情况下,将环境设置为测试并运行 artisan 命令:

APP_ENV=testing php artisan test

【讨论】:

相同。事实上,问题是环境设置不正确,即使我明确添加了它。在调用中间件之前,有些东西正在覆盖它【参考方案3】:

您的数据数组错误。尝试以下更改:

$response = $this->postJson(route('order.insert'), [
      'product_id' => $product->id, // use the arrow notation here.
 ]);

【讨论】:

是的,这是一个错字,已修复,但我仍然收到异常“预期状态代码 200 但收到 419。无法断言 false 为真。”也许是我想念的超级明显的东西.. 这就是我的路由在 web Route::post('/order', 'OrderController@insert')->name('order.insert'); 中定义的方式; 在运行测试之前尝试运行php artisan cache:clear 我修复了它,它来自配置缓存。我还必须从 phpunit.xml 中删除有关 DB_CONNECTION sqlite 和 DB_DATABASE 的行。感谢所有提示! 明确地说,是 php artisan config:clear 命令为我解决了问题

以上是关于为啥我在 laravel 中运行测试时收到“CSRF 令牌不匹配”?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在第二次运行测试时在 Mongoose 中收到错误“一旦编译后无法覆盖模型”?

为啥我在运行 Locust 时收到 403 错误?

为啥我在 Selenium 中收到 AssertionError?

为啥我在 Laravel 中收到“Route [/login] not defined 错误”?

为啥 Laravel 中的 PHPUnit 不能访问存在的路由?

为啥我在作曲家安装后在 Laravel 中收到 500 服务器错误 [关闭]