【问题标题】:How to assert in laravel 5.4 that each record in the list has at least enlisted attributes?如何在 laravel 5.4 中断言列表中的每条记录至少具有登记属性?
【发布时间】:2017-06-12 05:23:43
【问题描述】:

我只是将应用程序从 laravel 5.3 移动到 5.4。 在我的 API 测试中的 laravel 5.3 中,我可以验证响应中的每条记录都具有以下代码的属性:

$this->json('get', '/api/course-types')
        ->seeJsonStructure([
            '*' => ['id', 'aaa', 'bbb', 'ccc', 'ddd']
        ]);

我如何使用 laravel 5.4 做同样的事情?

Illuminate/Foundation/Testing/TestResponse中没有这种方法

【问题讨论】:

  • 是的,它已经消失了。您可以使用assertJson,也可以复制code for seeJsonStructure。需要明确的是,它从来不在TestResponse 中,而是在MakesHttpRequests trait 中。

标签: php laravel laravel-5 phpunit laravel-5.4


【解决方案1】:

我也经常使用seeJsonStructure(),所以我拼凑了一个小替代品来放置我自己的TestCase。希望它对某人有所帮助,或者有人可以建议我更好的解决方案:

添加到我的TestCase:

public function seeJsonStructure(TestResponse $response = null, array $structure = null, $responseData = null)
{
    if ($response && !$responseData) {
        $responseData = $response->decodeResponseJson();
    }
    if (is_null($structure)) {
        return $response->assertJson($responseData);
    }
    foreach ($structure as $key => $value) {
        if (is_array($value) && $key === '*') {
            $this->assertInternalType('array', $responseData);
            foreach ($responseData as $responseDataItem) {
                $this->seeJsonStructure(null, $structure['*'], $responseDataItem);
            }
        } elseif (is_array($value)) {
            $this->assertArrayHasKey($key, $responseData);
            $this->seeJsonStructure(null, $structure[$key], $responseData[$key]);
        } else {
            $this->assertArrayHasKey($value, $responseData);
        }
    }
    return $this;
}

然后,我必须更新我的测试,所以我在调用此方法时将响应作为第一个参数传递。 SomeTest 的示例:

$response = $this->json('POST', $url, [
    'id' => $user->id
]);

$this->seeJsonStructure($response, [
    'id', 'first_name', 'last_name', 'email'
]);

原来的 Laravel 方法是:https://github.com/laravel/browser-kit-testing/blob/85f9a14a63bf5a287740002fcbc4352587f8a113/src/Concerns/MakesHttpRequests.php#L348

【讨论】:

    【解决方案2】:

    browserkit 测试功能被 Laravel Dusk 取代。原始功能已移至其自己的包中:laravel/browser-kit-testing

    这个包为 Laravel 5.4 上的 Laravel 5.3 风格的“BrowserKit”测试提供了向后兼容层。

    您需要遵循该软件包的安装和使用说明,然后您现有的测试将像在 5.3 中一样工作。

    【讨论】:

    • 没用。现在相同的测试失败了 2 个错误:1) PHPUnit_Framework_Exception: Argument #1 (No Value) of PHPUnit_Framework_Assert::assertJson() must be a string 2) Error: Call to undefined method Tests\Feature\ExampleTest::assertStatus()
    • @gandra404 听起来您正在混合使用两个测试套件。一个测试类只能使用新的测试功能(Laravel Dusk)或旧的测试功能(BrowserKit)。 seeJsonStructure() 仅在 BrowserKit 测试套件中可用。 assertStatus() 仅在 Dusk 测试套件中可用。
    • 这很奇怪。我正在为 API 后端应用程序编写测试。没有可视界面,只有 REST 端点,我对一个端点的期望是: - 查看 json 响应 - 检查 http 状态代码 - 检查 json 响应是否具有特定结构,现在我必须将其拆分为 2不同的测试?如果这是真的,那我就有新问题了。
    • @gandra404 基本上,如果您尝试使用旧的 BrowserKit 套件,请查看 Laravel 5.3 的 testing documentation。如果您尝试使用新的 Dusk 套件,请查看 Laravel 5.4 的 testing documentation。例如,如果使用 Dusk,您将使用新的 assertStatus() 方法,但如果使用 BrowserKit,您将使用旧的 assertResponseStatus() 方法。
    • 我对使用 Dusk 或 BrowserKit 没有任何偏好。我只是作为如何制作适用于 laravel 5.3 的测试以传递 laravel 5.4 而不是将它们分成不同的类?
    【解决方案3】:

    相信您正在寻找assertJson()assertExactJson()

    来自docs

    assertJson 方法将给定数组转换为 JSON,然后验证 JSON 片段是否出现在应用程序返回的整个 JSON 响应中的任何位置。因此,如果 JSON 响应中有其他属性,只要存在给定的片段,此测试仍然会通过。

    及相关代码:

    $response = $this->json('POST', '/user', ['name' => 'Sally']);
    
    $response
        ->assertStatus(200)
        ->assertJson([
            'created' => true,
        ]);
    

    assertExactJson() 将寻找完全匹配,而assertJson() 只是验证响应中是否存在您的参数。希望对您有所帮助!

    【讨论】:

    • 我想检查响应结构而不是内容。这不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-17
    • 1970-01-01
    • 1970-01-01
    • 2021-09-23
    • 1970-01-01
    • 2014-12-06
    • 1970-01-01
    相关资源
    最近更新 更多