【问题标题】:PHPUnit API Testing returns unauthenticated in some post requestsPHPUnit API 测试在某些发布请求中返回未经身份验证
【发布时间】:2022-01-20 11:12:33
【问题描述】:

我正在尝试测试我的 Laravel API,但在某些情况下,当我提交一个发布请求时,我会收到一个 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();
    }

【问题讨论】:

  • 首先,不要使用getenv,如果 Laravel 改变了它的用途,getenv 将开始失败......你必须使用envconfig。 ..此外,在您的测试中,永远不要调用超过 1 个端点...您必须设置在那一刻您期望拥有的所有内容...因为如果以前的 API 中的一个失败并创建或返回错误的东西,那么您就是为该测试完成...

标签: php laravel testing phpunit laravel-sanctum


【解决方案1】:

您的部分问题是您将标题数据和帖子数据混合在一起。你应该尝试使用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);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-02
    • 1970-01-01
    相关资源
    最近更新 更多