Laravel功能测试中模拟外部数据库查询返回空结果的问题排查
Laravel功能测试中模拟外部数据库查询返回空结果的问题排查
看起来你遇到的问题是测试里模拟settings表查询时返回了空结果,我帮你梳理下问题所在和解决方法:
1. 核心问题:查询条件参数不匹配
仔细对比你的测试代码和实际业务代码,发现了一个细节差异:
- 测试中模拟
settings表查询的where条件:
DB::shouldReceive('where')->with('setting', 'mysettings')->andReturnSelf();
- 实际业务代码(job里的查询):
->where('setting', 'mysetting')
看到了吗?测试里写的是'mysettings'(多了一个末尾的s),而实际代码里的条件值是'mysetting'。Mockery的模拟是严格匹配参数的,这就导致你的模拟调用没有被触发,DB::get()自然就返回了空结果,而不是你定义的$settingsDirect。
2. 快速修复方案
把测试里的where条件参数改成和实际代码完全一致的即可:
DB::shouldReceive('where')->with('setting', 'mysetting')->andReturnSelf();
3. 额外的排查建议
为了避免以后再遇到类似问题,给你几个小技巧:
- 严格匹配链式调用顺序:Laravel数据库查询的链式调用顺序必须和模拟的顺序完全一致,比如实际代码是
connection()->table()->where(),测试里的模拟也要按这个顺序来。 - 启用Mockery严格模式:给模拟调用加上
->strict(),这样当有未被模拟的DB调用发生时,会直接抛出异常,帮你快速定位不匹配的地方:
DB::shouldReceive('connection')->with('externalconnection')->andReturnSelf()->strict();
- 检查job中的DB连接:如果你的job里使用了队列,要确保测试中对DB的模拟覆盖到了job执行时的上下文,比如可以在测试中调用
Queue::fake()或者直接同步执行job来验证。
备注:内容来源于stack exchange,提问作者Fil
相关产品推荐
相关产品推荐

