Laravel API测试中seeJson报Call to a member function assertJson() on null错误求助
Laravel测试报错:Call to a member function assertJson() on null 解决办法
问题重现
你编写的测试代码如下:
public function testFirstAPI() { $user = \User::find(1); $r = $this ->actingAs($user) ->json('put', route('updateUser'),['lock' => 'true']); $r->assertResponseStatus(200)->seeJson(['success' => true]); }
测试可以正常运行,通过$r->dump()也能在响应里找到success字段,但链式调用seeJson时却抛出错误:[Symfony\Component\Debug\Exception\FatalErrorException] Call to a member function assertJson() on null。
问题原因
这个错误的核心是链式调用中方法的返回值不符合预期:
$this->actingAs()->json()返回的是TestResponse对象,这一步没问题;- 但
assertResponseStatus(200)这个方法,在部分Laravel版本中(或其设计逻辑)并不会返回TestResponse对象,而是返回TestCase实例或者直接无返回值; - 这就导致后续调用
->seeJson()时,实际上是在null或非响应对象上执行,而seeJson内部会尝试调用assertJson(),自然就触发了“在null上调用方法”的错误。
另外还有一个可能:seeJson本质是TestCase类的方法,而非TestResponse的方法,你直接在$r上调用它本身就不符合API设计逻辑。
解决办法
这里给你几个可行的修复方案,你可以根据自己的Laravel版本选择:
方案1:拆分链式调用,分开执行断言
最简单的修复方式就是把链式调用拆成独立的两行,确保每个断言都作用在正确的对象上:
public function testFirstAPI() { $user = \User::find(1); $r = $this->actingAs($user)->json('put', route('updateUser'), ['lock' => 'true']); // 分开执行两个断言 $r->assertResponseStatus(200); $r->seeJson(['success' => true]); }
方案2:使用TestResponse的原生断言方法(推荐给新版本Laravel)
如果你的Laravel版本在5.5及以上,TestResponse提供了更贴合响应对象的assertJson方法,同时可以用assertStatus替代旧的assertResponseStatus:
public function testFirstAPI() { $user = \User::find(1); $r = $this->actingAs($user)->json('put', route('updateUser'), ['lock' => 'true']); $r->assertStatus(200); $r->assertJson(['success' => true]); }
方案3:在测试类实例上调用seeJson
如果你的项目使用的是较老的Laravel版本(比如5.2及之前),seeJson是TestCase的方法,应该直接在$this上调用:
public function testFirstAPI() { $user = \User::find(1); $this->actingAs($user)->json('put', route('updateUser'), ['lock' => 'true']); $this->assertResponseStatus(200); $this->seeJson(['success' => true]); }
验证建议
修改代码后,你可以先单独调用$r->dump()确认响应结构,再逐步添加断言,这样能快速定位是否还有其他潜在问题。
内容的提问来源于stack exchange,提问作者MajAfy
相关产品推荐
相关产品推荐

