如何在Laravel中测试POST路由

时间:2015-03-01 05:12:25

标签: php laravel phpunit

我正在执行以下操作来测试对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');
    }

但是,我告诉我重定向不匹配。此外,我可以看到它根本没有进入商店行动方法。我想知道它将采取什么行动方法,以及它为什么不去存储方法(如果我查看路线:列表我可以看到有一个POST问题/路线应该转到questions.store ;这也适用于浏览器,但不适用于我的测试)。此外,我正在为此资源正确编写呼叫吗?我在这里添加了令牌,因为它正在抛出异常,在某些测试中我会让令牌检查通过。

5 个答案:

答案 0 :(得分:5)

你可以试试这个:

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

答案 1 :(得分:2)

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

为此,请使用:

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

    $this->assertEquals(200, $response->getStatusCode());
}

答案 2 :(得分:0)

没有中间件的Laravel Unit案例

    use WithoutMiddleware;

    protected $candidate = false;

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

        $this->candidate = new Candidate();
    }   

    /** @test */
    public function 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 :(得分:0)

我使用

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

以便确认验证工作。但是要使用此功能,您必须从要发送帖子请求的页面开始。像这样:

$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');

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

答案 4 :(得分:-1)

我得到一个TokenMismatchException并解决了这个问题,也许对您也有帮助

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

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