Laravel10+Pest测试MailerSend时出现未初始化属性错误
解决MailerSend客户端测试中“Typed property must not be accessed before initialization”错误
问题原因
真实的MailerSend实例在构造时会自动初始化bulkEmail等子客户端属性,但测试中创建的Mock对象不会执行原类的构造逻辑,导致直接访问$mailerSendClient->bulkEmail时触发未初始化的类型属性错误。
解决方案
调整Mock的写法,先模拟bulkEmail属性的访问,返回一个Mock对象,再模拟该对象的send方法:
it('sends an email', function () { Config::set('services.mailersend.key', 'foo'); $this->mock(MailerSend::class, function (MockInterface $mock) { // 创建bulkEmail的Mock对象 $bulkEmailMock = Mockery::mock(); $bulkEmailMock->shouldReceive('send') ->once() ->andReturn([ 'response' => 'success', 'data' => [ 'status_code' => 202, ], 'body' => [ 'bulk_email_id' => '123foo' ] ]); // 让MailerSend的Mock返回这个bulkEmail Mock $mock->shouldReceive('bulkEmail') ->andReturn($bulkEmailMock); }); actingAsAdmin(); postJson(route($this->route, $this->payload)) ->assertOk(); });
原理说明
原测试中使用的shouldReceive('bulkEmail->send')是Mockery的链式调用语法,但Laravel的Mock包装在处理这种嵌套属性访问时,不会自动初始化bulkEmail属性。通过显式模拟bulkEmail属性的返回值,确保Action中访问$mailerSendClient->bulkEmail时能拿到一个有效的Mock对象,进而调用其send方法。
内容的提问来源于stack exchange,提问作者Andrea Giovinazzi
相关产品推荐
相关产品推荐

