【问题标题】:Laravel REST API Testing in phpunitphpunit 中的 Laravel REST API 测试
【发布时间】:2021-04-04 18:09:36
【问题描述】:

我正在尝试通过 phpunit 测试 Laravel REST API。在测试 REST 调用时,我无法隔离 REST 调用测试。

在 Laravel 中,我了解一些选项,例如使用特征 DatabaseMigrationsDatabaseRefreshDatabaseTransactions。但我不能使用这些,原因如下:

  • DatabaseMigrations: 应用没有正确的迁移。就算有,那也是相当低效的。

  • DatabaseRefresh:同上。

  • DatabaseTransactions。我看到的问题是对 HTTP API 的调用是一个完全不同的过程。这些不在同一个事务中。因此,HTTP 调用看不到插入数据以设置测试用例的测试。此外,如果数据是通过 HTTP 调用插入的,其他测试也可以看到。

如果不调用 HTTP,我就无法编写单元测试;该应用程序不是以这种方式编写的。整个代码位于 RoutesController 中,否则不可测试。

【问题讨论】:

  • 如果您没有以不符合 sqlite 的方式构建计划的生产数据库 - 那么定义正确的迁移将是一个很好的步骤。然后,您可以使用内存中的 sqlite 进行 DatabaseMigrations 或 RefreshDatabase 测试,测试仍然会很快 - 只是一个想法
  • @Donkarnash 创建整个模式的迁移将非常困难,尽管并非不可能。一旦找到可以自动执行此操作的工具,我将尝试一下,我的意思是获取一个 sql 并将其转换为 Laravel Migration/Seeder。但是,我仍在寻找可能处理事务的解决方案。这也许是阻力最小的路径。
  • 你能解释一下为什么API调用是一个完全不同的事务吗?你试过写一个简单的测试用例吗?如果是的话,你能给我们看看代码吗?
  • 我认为您的误解是您打算通过网络使用 HTTP 请求调用 API。在 Laravel 中,你有 HTTP 测试,请参阅laravel.com/docs/8.x/http-tests 的文档以获取更多信息。测试的整个想法是您始终使用模拟实例。您还如何防止应用程序触发真实事件或写入您的开发甚至生产数据库而不是测试数据库?

标签: laravel rest phpunit


【解决方案1】:

所以在我的例子中void 意味着我们的方法没有返回任何东西。 postJson 表示我们期望 JSON 响应,或者我们可以只做 $this->post()

你可以这样打电话

public function test_create_order() : void
    {
        $response = $this->postJson('/make-order',[
            'foo' => 'bar',
            'baz' => 'bat'
        ]);

        // To make sure it is returning 201 created status code, or other code e.g. (200 OK)
        $response->assertStatus(201);

        // To make sure it is in your desired structure 
        $response->assertJsonStructure([
                'id',
                'foo',
                'baz',
        ]);
 
        // Check if response contains exactly that value, what we inserted
        $this->assertEquals('bar', $response->json('data.foo'));

        // Check that in the database created that record,
        // param 1 is table name, param 2 is criteria to find that record
        // e.g. ['id' => 1]
        $this->assertDatabaseHas('orders', [
            'foo' => 'bar'
        ]);
        // Also there is other method assertDatabaseMissing, that works like above
        // just in reverse logic, it is checking that there is no record with that criteria
       
    }

【讨论】:

  • 在一个测试中从其他测试中删除订单有点奇怪,您可以use DatabaseTransactions 使数据库保持不变。
【解决方案2】:

我使用 json 函数测试我的端点(我相信也有 POST 和 GET 方法,但我需要传入数据和标头)

public function test_endpoint() {
        $result = $this->json('POST', '/api', ['key' => 'data'], ['Header' => "Value"]);
}

我也有单元和功能测试,但我用它来测试 graphQL 端点。

【讨论】:

    猜你喜欢
    • 2014-12-31
    • 2012-09-08
    • 2018-05-24
    • 2015-09-26
    • 2017-11-29
    • 2018-03-27
    • 2012-07-16
    • 2019-06-06
    • 2017-10-19
    相关资源
    最近更新 更多