Laravel测试中assertJsonMissing仅传键无效?原因及正确用法
Laravel测试中assertJsonMissing断言的问题解析
我正在开展一个TDD项目,需确保/api/profile/info接口不会误返回password字段,编写的测试代码如下:
public function testInfoMethodJsonStructure() { $user = User::factory()->create(); $response = $this ->actingAs($user) ->get('/api/profile/info'); $response->assertStatus(200); $response->assertJsonStructure(['name', 'fullname', 'email']); $response->assertJsonMissing(['password']); // 此用例通过 $response->assertJsonMissing(['password' => $user->password]); // 此用例未通过 }
已知接口实际返回了password字段,但为何仅传递键的assertJsonMissing断言未生效?若该用法不正确,检查字段缺失的正确方式是什么?
问题原因
- Laravel的
assertJsonMissing(['password'])断言逻辑是:检查响应JSON的顶层数据中是否不存在完整的password键值对。如果接口返回的password是嵌套在子结构(比如data对象)中,或者框架序列化时对password值做了处理(比如自动哈希,和你直接获取的$user->password值不匹配),这个断言就会错误地认为顶层没有该字段,从而通过。 - 而
assertJsonMissing(['password' => $user->password])未通过,是因为接口返回的password值和你传入的$user->password不一致,断言准确检测到了这个键值对存在,因此失败。
正确的字段缺失检查方式
精准检查字段是否存在(推荐)
使用assertJsonMissingPath方法,它会直接检查指定路径的字段是否存在,不受值的影响:// 检查顶层是否无password字段 $response->assertJsonMissingPath('password'); // 如果字段在嵌套结构中,比如data.password $response->assertJsonMissingPath('data.password');检查键值对是否完全不存在
如果需要确认某个特定键值对不存在,必须保证传入的值和接口返回的完全一致。比如接口返回的是哈希后的密码,直接用数据库中存储的哈希值断言:$response->assertJsonMissing(['password' => $user->password]);
内容的提问来源于stack exchange,提问作者roozmehr knight
相关产品推荐
相关产品推荐

