Laravel单元测试报错:assertJson实际与预期不匹配求助
Laravel单元测试assertJson断言失败问题解决
问题描述
我是Laravel单元测试新手,测试时遇到assertJson断言失败,实际返回JSON与预期不匹配。相关代码如下:
测试代码
/** @test */ public function users_can_view_homepage_products() { $response = $this->get('api/products'); $response->assertStatus(200) ->assertJson([ 'id' => 1, 'name' => ucwords($this->faker->words(3, true)), 'slug' => ucfirst($this->faker->slug), 'intro' => $this->faker->sentence, 'price' => number_format($this->faker->randomFloat(2, 100, 99999), 2) ]); }
控制器代码
public function index() { return [ 'id' => 1, 'name' => 'Airpods Pro (2021)', 'slug' => 'airpods-pro-2021', 'intro' => 'New and powerful airpods from apple.', 'price' => 12400 ]; }
错误信息
assertJson断言失败,实际返回JSON与预期不匹配。
问题原因及解决方法
问题核心是测试代码里的assertJson用了Faker生成的随机值,但控制器返回的是固定硬编码数据,两者完全不匹配,导致断言失败。有两种解决思路:
- 匹配控制器返回的固定值
直接把assertJson的预期值改成控制器实际返回的内容:
/** @test */ public function users_can_view_homepage_products() { $response = $this->get('api/products'); $response->assertStatus(200) ->assertJson([ 'id' => 1, 'name' => 'Airpods Pro (2021)', 'slug' => 'airpods-pro-2021', 'intro' => 'New and powerful airpods from apple.', 'price' => 12400 ]); }
- 验证JSON结构而非具体值
如果后续控制器会返回动态数据(比如从数据库读取),更合理的做法是验证返回JSON的结构是否符合预期,而非具体内容,这时用assertJsonStructure:
/** @test */ public function users_can_view_homepage_products() { $response = $this->get('api/products'); $response->assertStatus(200) ->assertJsonStructure([ 'id', 'name', 'slug', 'intro', 'price' ]); }
如果要测试动态生成的数据,需先在测试中创建对应的测试数据(比如通过模型工厂生成产品并保存到测试数据库),再断言返回的数据与创建的测试数据一致。
内容的提问来源于stack exchange,提问作者Blues Clues
相关产品推荐
相关产品推荐

