【问题标题】:Feature test for HTTP RESTful API on Laravel 8Laravel 8 上的 HTTP RESTful API 功能测试
【发布时间】:2021-06-08 14:14:42
【问题描述】:

我正在尝试使用我在 laravel 8 中创建的 RESTful API 编写功能测试。 我有ChatController 通过getUserChats 方法获取用户聊天:

// get chats for user
public function getUserChats()
{
    $chats = $this->chats->getUserChats();
    return ChatShowResource::collection($chats);
}

这条路线调用的:

Route::get('chats', [
    App\Http\Controllers\Chats\ChatController::class, 'getUserChats'
]);

这是我在这条路线上的功能测试:

public function test_get_user_chats()
{
    // creates the fake user
    $user = User::factory()->create();
    $this->actingAs($user, 'api');

    // adds the chat to new fake user that created
    $response_create_chat = $this->json('POST', '/api/chats', [
            'recipient' => $user->username,
            'body' => 'some chat text',
        ]
    );

    $response_create_chat
        ->assertStatus(201)
        ->assertJsonPath('data.body', 'some chat text');

    $response_get_chats = $this->json('get', '/api/chats');

    $response_get_chats->assertStatus(200);
}

此绿色输出OK (1 test, 3 assertions) 成功运行测试,但我不知道这是实现它的最佳方式。

所以问题是我在测试中还需要做什么?我在做正确的功能测试吗?

【问题讨论】:

    标签: php laravel testing phpunit laravel-8


    【解决方案1】:

    通常,您希望测试的范围尽可能小。您提供的测试用例目前正在测试两个单独的 api 端点:

    • 创建聊天
    • 聊天

    这样做的问题是,如果与创建聊天相关的代码中断,那么与获取聊天相关的测试用例将失败。

    我建议将它们分成两个单独的测试用例。这将让您相信,如果您获取聊天的测试用例失败,那是因为与获取聊天相关的代码失败,而不是与此端点无关的代码。

    我还建议使用setUptearDown 方法来确保您的测试用例使数据库处于与找到它时相同的状态。这确保了其他测试用例不必关心来自该测试的数据。这意味着setUp 方法应该执行以下操作:

    • 创建用户
    • 创建聊天

    tearDown 方法将负责删除用户和聊天。

    此外,您应该测试端点输出的格式和数据。目前,您只检查 200 响应代码。如果您的 api 更新为返回用户列表而不是聊天记录,则与获取聊天记录相关的测试用例仍将通过,因为它实际上并未验证返回的数据。

    前:

    class GetChatsTest extends TestCase
    {
        private User $user;
        
        public function testGetChats(): void
        {
            $chat = $this->json('get', '/api/chats');
            // Check the chat's returned value
            $this->assertSame('Some parameters', $chat);
        }
    
        protected function setUp(): void
        {
            parent::setUp();
            // Create the user in the setup. This is run before each test method is run.
            $this->user = User::factory()->create();
            // Create the chat for the user (Pseudo code because I don't know how your code works)
            $this->user->createChat('Some parameters');
        }
    
        protected function tearDown(): void
        {
            parent::tearDown();
            // Delete the user and chats here, pseudocode again. This runs after every test method is run
            $this->user->deleteChats();
            $this->user->delete();
        }
    }
    

    关于示例代码需要注意的一点是,它不使用 rest api 来创建用户或聊天,而是使用伪代码控制器方法来确保它不依赖于聊天 api 的功能进行测试.

    【讨论】:

    • 您能否编辑您的答案并添加一些有关使用 setUp 和 tearDown 的代码?
    • 那么我们在哪里为新用户分配(创建)聊天?
    • 这将在setUp 方法中完成,因为您正在准备环境以测试获取聊天列表的代码。
    猜你喜欢
    • 2013-08-02
    • 2021-12-24
    • 2022-12-18
    • 1970-01-01
    • 1970-01-01
    • 2020-03-31
    • 2019-11-02
    • 2021-01-31
    • 2021-09-07
    相关资源
    最近更新 更多