【问题标题】:How to test POST routes in Laravel如何在 Laravel 中测试 POST 路由
【发布时间】:2015-05-01 15:46:23
【问题描述】:

我正在执行以下操作来测试对 Laravel 的 POST 调用。根据我的路线,我希望对问题的 POST 将作为存储操作方法进行调度。这适用于浏览器。

我的测试:

public function setUp()
    {   
        parent::setUp();

        Session::start();
    }

    public function testStoreAction()
    {
        $response = $this->call('POST', 'questions', array(
            '_token' => csrf_token(),
        ));

        $this->assertRedirectedTo('questions');
    }

但是,我告诉我重定向不匹配。另外,我可以看到它根本不会使用 store 操作方法。我想知道它要使用什么操作方法,以及为什么它不使用 store 方法(如果我查看 route:list 我可以看到有一个 POST questions/route 应该转到 questions.store;这个也适用于浏览器,但不适用于我的测试)。另外,我是否为此资源正确编写了调用?我在这里添加了令牌,因为它应该抛出异常,在某些测试中我会让令牌检查通过。

【问题讨论】:

  • 能否提供实际的错误描述,谢谢
  • 您的 POST 参数不太可能只是 csrf 令牌。可能在您的控制器中,您有某种验证,使请求重定向回之前的位置(302 响应代码)。您可以通过使用dd(Session::get('errors')) 调试会话来检查是否是这种情况

标签: php laravel phpunit


【解决方案1】:

我用

$response->assertSessionHasErrors(['key'=>'error-message']);

为了断言验证工作。但是要使用它,您必须从要发送 post 请求的页面开始。像这样:

$user = User::where('name','Ahmad')->first(); //you can use factory. I never use factory while testing because it is slow. I only use factory to feed my database and migrate to make all my test faster.
$this->actingAs($user)->get('/user/create'); //This part is missing from most who get errors "key errors is missing"
$response = $this->post('/user/store', [
                '_token' => csrf_token()
            ]);
//If you use custom error message, you can add as array value as below.
$response->assertSessionHasErrors(['name' => 'Name is required. Cannot be empty']);
$response->assertSessionHasErrors(['email' => 'Email is required. Make sure key in correct email']);

然后,如果您想测试错误是否也正确显示回来。再次运行上面的测试并进行一些更改,如下所示:

$this->actingAs($user)->get('/user/create'); 
$response = $this->followingRedirects()->post('/user/store', [
                '_token' => csrf_token()
            ]); //Add followingRedirects()
$response->assertSeeText('Name is required. Cannot be empty');
$response->assertSeeText('Email is required. Make sure key in correct email');

我的猜测是,如果您不从显示错误的页面开始(您放置表单的创建/更新页面),则在此过程中的会话链会丢失一些重要的键。

【讨论】:

    【解决方案2】:

    没有中间件的 Laravel 单元案例

    使用无中间件; 受保护的 $candidate = false; 公共功能设置():无效 { 父::setUp(); $this->candidate = new Candidate(); } /** @测试 */ 公共函数 it_can_get_job_list() { $this->actingAs($this->user, 'api'); $response = $this->candidate->getJobsList(); $this->assertNotNull($response); $this->assertArrayHasKey('data', $response->toArray()); $this->assertNotEmpty($response); $this->assertInternalType('object', $response); }

    【讨论】:

      【解决方案3】:

      我收到了一个 TokenMismatchException 并修复了它,也许它也可以帮助你

      public function testStoreAction()
      {
          $response = $this->withSession(['_token' => 'covfefe'])
              ->post('questions', [
                  '_token' => 'covfefe',
              ));
      
          $this->assertRedirectedTo('questions');
      }
      

      【讨论】:

        【解决方案4】:

        你可以试试这个:

        public function testStoreAction()
        {
            Session::start();
            $response = $this->call('POST', 'questions', array(
                '_token' => csrf_token(),
            ));
            $this->assertEquals(302, $response->getStatusCode());
            $this->assertRedirectedTo('questions');
        }
        

        【讨论】:

          【解决方案5】:

          最推荐的测试路由的方法是检查200 响应。这在您进行多项测试时非常有用,例如您同时检查所有 post 路由。

          为此,只需使用:

          public function testStoreAction()
          {
              $response = $this->call('POST', 'questions', array(
                  '_token' => csrf_token(),
              ));
          
              $this->assertEquals(200, $response->getStatusCode());
          }
          

          【讨论】:

          • 但此操作未返回 200 代码,我正在重定向用户 (30x),并且我想确认他们转到了正确的 URL(问题)。
          猜你喜欢
          • 2019-11-15
          • 1970-01-01
          • 2018-01-26
          • 2021-01-26
          • 1970-01-01
          • 2016-04-07
          • 1970-01-01
          • 1970-01-01
          • 2018-04-05
          相关资源
          最近更新 更多