使用 Laravel 测试 JSON 响应

Posted

技术标签:

【中文标题】使用 Laravel 测试 JSON 响应【英文标题】:Testing JSON response with Laravel 【发布时间】:2019-02-19 10:57:16 【问题描述】:

我使用 Laravel 准备了一个示例 API。它总是返回这个对象:


    "a": 1,
    "b": 2

现在,我想更好地了解如何使用phpunit 对其进行测试。我发现有assertJsonassertJsonFragment 方法,我无法理解它们之间的区别。

假设我想断言响应的确切结构,所以它需要是 a=1b=2,仅此而已。起初,我确信这会奏效:

$response = $this->get('/api/foo');

$response->assertStatus(200)
         ->assertJson(['a' => 1, 'b' => 2]);

它会通过测试,但问题是如果我在响应中添加更多属性,它仍然可以通过测试,比如c=3 或其他。然后是 assertJsonFragment 方法,对于我的测试,它的行为相同,只是给出不同的错误消息。

assertJson 有问题吗?有没有其他方法可以做我想做的事情,即确保响应是这组特定的属性?

在 Laravel 5.6 和 5.7 上测试。

【问题讨论】:

【参考方案1】:

来自here:

assertJson 方法将响应转换为数组并利用 PHPUnit::assertArraySubset 验证给定数组是否存在 在应用程序返回的 JSON 响应中。所以,如果有 JSON 响应中的其他属性,此测试仍将通过 只要给定的片段存在。

更重要的是,实现你想要的:

如果您想验证给定数组是否与应用程序返回的 JSON 完全匹配,您应该使用 assertExactJson 方法

【讨论】:

assertExactJson 是我去那里的方式。 你知道assertJsonFragment是做什么的吗? @RoboRobok assertJson 正在检查您提供的每个键值对,以查看它是否存在于响应中的 anywhere (在任何嵌套级别),而 assertJsonFragment 正在搜索您对您提供的确切片段的回复。 This video 解释得很好。它使用较旧的seeJson/seeJsonSubset 语法而不是assertJson/assertJsonFragment,但一般信息是正确的。 那个命名约定没有多大意义。如果有的话,应该是相反的。 是的,有很多人倾向于同意,不幸的是官方文档有点缺乏理解差异。

以上是关于使用 Laravel 测试 JSON 响应的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 尝试对 API JSON 响应进行单元测试

Laravel 控制器返回索引视图而不是 json 响应

如何从 Windows 命令提示符在 Laravel 中运行 PHPUnit

Laravel 5.1 使用 JSON 的 API 的 PHPUnit 测试

Laravel 功能测试响应原始属性

Laravel 5.2 PHPUnit JSON Api 请求正文未设置