You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用mockery/mockery为Laravel DB门面的when方法创建测试桩

你需要为when方法创建测试桩,若要同时验证闭包内的逻辑是否正确执行,可参考以下实现方案:

完整测试代码(支持闭包逻辑验证)

public function test_example()
{
    // 创建查询构造器Mock对象
    $queryMock = \Mockery::mock(\Illuminate\Database\Query\Builder::class);
    
    // 模拟DB::table调用,返回构造器Mock
    DB::shouldReceive('table')
        ->once()
        ->with('users')
        ->andReturn($queryMock);

    // 模拟when方法,对齐Laravel原生逻辑,条件成立时执行闭包
    $queryMock->shouldReceive('when')
        ->once()
        ->with(true, \Mockery::type(\Closure::class))
        ->andReturnUsing(function ($condition, $closure) use ($queryMock) {
            if ($condition) {
                $closure($queryMock);
            }
            return $queryMock;
        });

    // 验证闭包内的where方法是否被正确调用
    $queryMock->shouldReceive('where')
        ->once()
        ->with('email_verified_at', null)
        ->andReturnSelf();

    // 模拟get方法调用
    $queryMock->shouldReceive('get')
        ->once()
        ->andReturn(collect([]));

    // 执行业务代码
    (new \App\TestRepo())->testQb();
    
    $this->assertTrue(true);
}

简化版测试代码(仅保证不报错,不验证闭包逻辑)

如果不需要校验闭包内的执行逻辑,仅需要测试跑通,可以用更简单的桩实现:

public function test_simple()
{
    DB::shouldReceive('table')->once()->with('users')->andReturnSelf();
    DB::shouldReceive('when')->once()->andReturnSelf();
    DB::shouldReceive('get')->once()->andReturn(collect([]));
    
    (new \App\TestRepo())->testQb();
    $this->assertTrue(true);
}

核心说明

  • 单独创建查询构造器的Mock对象,而非复用DB门面自身作为返回值,更贴合Laravel的实际运行逻辑:DB::table()本身会返回Illuminate\Database\Query\Builder实例,而非DB门面实例。
  • 使用andReturnUsing处理when的桩逻辑,可以完全复现原生when的行为,确保闭包被正确触发。
  • 对where方法增加调用校验,可以确保闭包逻辑确实被执行,且参数符合预期,测试覆盖度更高。

内容的提问来源于stack exchange,提问作者KevDev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 17:45:02