PHPUnit API 测试 returns 在某些 post 请求中未经身份验证

PHPUnit API Testing returns unauthenticated in some post requests

我正在尝试测试我的 Laravel API,但在某些情况下,当我提交 post 请求时,我会收到 401 错误消息“未验证”。所有受保护的 GET 请求都可以正确访问,某些 POST 请求(如提交状态)也可以正常访问。为什么我在某些情况下会收到 401 错误,而在其他情况下却不会?

这是文件
API 路线

Route::group(['middleware' => ['auth:sanctum']], function() {
    Route::get('logout', [MantelAuthController::class, 'logout']);
    
    Route::post('status', [MantelController::class, 'status']);
    Route::post('deleteAccount', [MantelController::class, 'deleteAccount']);
});

注销测试

public function test_logoutAPI()
    {
        $testEmail = getenv('TEST_EMAIL_API');
        $testPassword = getenv('TEST_PASSWORD_API');

        $response = $this->post('/api/login', [
            'email' => $testEmail,
            'password' => $testPassword
        ]);

        $auth =  $response->assertStatus(201)->decodeResponseJson()['token'];
        
        $response = $this->get('/api/logout', 
        [
            'Authorization' => "Bearer ".$auth
        ]);
        $response->assertStatus(200);
    }

发送状态测试

public function test_post_status()
    {
        $testEmail = getenv('TEST_EMAIL_API2');
        $testPassword = getenv('TEST_PASSWORD_API');

        // log in
        $response = $this->post('/api/login', [
            'email' => $testEmail,
            'password' => $testPassword
        ]);
        $auth = $response->assertStatus(201)->decodeResponseJson()['token'];

        // get correct datetime
        $response = $this->get('/api/getData', 
        [
            'Authorization' => "Bearer ".$auth
        ]);
        $date= $response->assertStatus(200)->decodeResponseJson()['date'];
        
        // submit post request
        $response = $this->post('/api/status', 
        [
            'Authorization' => "Bearer ".$auth,
            'status' => "secure",
            'date' => $date
        ]);
        $response->assertCreated();
    }

删除帐户测试

public function test_delete_account()
    {
        $DeletedEmail = "temporary@gmail.com";
        $DeletedPassword = "temporary";

        $response = $this->post('/api/login', [
            'email' => $DeletedEmail,
            'password' => $DeletedPassword
        ]);
        $auth = $response->assertStatus(201)->decodeResponseJson()['token'];
        
        $response = $this->withHeaders(['Accept' => 'application/json'])
        ->post('/api/deleteAccount', [
            'Authorization' => "Bearer ".$auth,
            'password' => $DeletedPassword
        ]);
        $response->assertSuccessful();
    }

部分问题是您将 header 数据和 post 数据混合在一起。您应该尝试使用 withHeaders

https://laravel.com/docs/8.x/http-tests#customizing-request-headers

$response = $this->withHeaders([
            'X-Header' => 'Value',
        ])->post('/user', ['name' => 'Sally']);

您也不必通过您的 API 路由请求为每个测试实际登录,因为这是非常低效的。您应该对登录 API 路由进行测试,但您应该访问用户模型并使用 actingAs 为其他请求设置身份验证。

https://laravel.com/docs/5.2/testing#sessions-and-authentication

<?php

class ExampleTest extends TestCase
{
    public function testApplication()
    {
        $user = factory(App\User::class)->create();

        $this->actingAs($user)
             ->withSession(['foo' => 'bar'])
             ->visit('/')
             ->see('Hello, '.$user->name);
    }
}