Mock方法未通过实例生效:Export类getBranches方法Mock失效排查
问题原因及解决方案
核心原因
new Export()绕过了Laravel服务容器
你通过$this->instance(Export::class, $mock)将mock实例绑定到了容器,但PHP原生的new关键字是直接创建类的新实例,完全不会和Laravel服务容器交互。所以你new出来的是真实的Export对象,自然会调用真实的getBranches方法返回数据库数据。静态方法无法通过实例Mock覆盖
静态方法属于类本身,而非实例。partialMock是针对类实例的Mock,无法影响静态方法的执行逻辑。而且静态方法的调用同样不会走服务容器,所以改静态方法也解决不了问题。
可行解决方案
从服务容器获取实例,而非直接
new
测试时不要用new Export(),改用容器获取实例:$export = app(Export::class); // 或者 $export = $this->app->make(Export::class);这样拿到的就是你绑定的mock实例,调用
getBranches会返回预设的空集合。修改业务代码的实例获取方式
如果业务代码里是直接new Export(),建议改成依赖注入的方式,比如在需要用到Export的类中通过构造函数注入:class SomeService { public function __construct(private Export $export) {} public function doSomething() { $branches = $this->export->getBranches(); } }测试时容器会自动注入你绑定的mock实例,无需手动处理。
Mock底层的
Branch::all()调用
如果不想修改实例获取方式,可以直接MockBranch模型的静态方法,让Branch::all()返回空集合:$this->mock(Branch::class, function ($mock) { $mock->shouldReceive('all')->andReturn(collect()); });这样不管是真实的
Export实例还是mock实例,调用getBranches都会返回空集合。
内容的提问来源于stack exchange,提问作者Gommiboum
相关产品推荐
相关产品推荐

