Laravel测试中如何Mock多层依赖的两个服务方法并解决属性未初始化报错
多层服务依赖Mock报错解决方法
报错原因
你遇到的报错是因为Laravel内置的partialMock方法创建Mock对象时,默认不会调用原类的构造函数,所以BillingPlanService的$userService属性没有完成初始化,访问时就触发了类型属性未初始化的错误。
正确实现代码
你可以手动构造Partial Mock实例,主动传入已经Mock好的UserService依赖,再绑定到容器中即可:
// 第一步:Mock UserService的getUsage方法,绑定到容器 $this->mock(UserService::class, function ($mock) { $mock->shouldReceive("getUsage")->andReturn([]); }); // 第二步:手动创建BillingPlanService的Partial Mock,传入容器中已Mock的UserService $billingPlanMock = \Mockery::mock(BillingPlanService::class, [app(UserService::class)]) ->makePartial(); // Mock需要重写的loadPlans方法 $billingPlanMock->shouldReceive("loadPlans")->andReturn([]); // 第三步:将Mock实例绑定到服务容器,替代原有服务 $this->app->instance(BillingPlanService::class, $billingPlanMock); // 第四步:正常发起测试请求 getJson(action([BillingPlanController::class, "getPlans"]));
额外说明
如果你要Mock的loadPlans是受保护(protected)方法,需要在创建Mock时加一行配置允许Mock非公共方法:
$billingPlanMock = \Mockery::mock(BillingPlanService::class, [app(UserService::class)]) ->shouldAllowMockingProtectedMethods() ->makePartial();
内容的提问来源于stack exchange,提问作者Mistre83
相关产品推荐
相关产品推荐

