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

Laravel+Pest测试:如何配置Mockery按方法调用参数返回对应值?

Laravel + Pest + Mockery 模拟 Dotenv 测试方案

核心思路

要实现针对Dotenv::createArrayBacked()的参数匹配,并让safeLoad()返回对应APP_URL,关键是利用Mockery的参数约束和链式调用模拟,同时通过Laravel容器替换真实的Dotenv实例。

具体实现步骤

1. 绑定模拟的Dotenv实例到容器

在测试用例中,先通过Mockery创建Dotenv的模拟对象,然后绑定到容器,确保Action中依赖注入的是模拟实例:

use Dotenv\Dotenv;

beforeEach(function () {
    // 创建Dotenv的Mock实例
    $dotenvMock = Mockery::mock(Dotenv::class);
    
    // 将Mock绑定到容器,覆盖真实实现
    app()->instance(Dotenv::class, $dotenvMock);
});

2. 匹配参数并指定返回值

针对不同的路径和文件名,用with()方法精确匹配参数,链式模拟safeLoad()返回对应环境变量数组:

it('returns correct APP_URL for .env.test', function () {
    $dotenvMock = app(Dotenv::class);
    
    // 模拟:传入base_path()和.env.test时,safeLoad返回指定APP_URL
    $dotenvMock->shouldReceive('createArrayBacked')
        ->with(base_path(), '.env.test')
        ->andReturnSelf() // 返回Mock自身,支持链式调用
        ->shouldReceive('safeLoad')
        ->andReturn(['APP_URL' => 'https://test.example.com']);
    
    // 执行Action并断言结果
    $action = app(YourEnvProcessingAction::class);
    $result = $action->handle(['test']);
    
    expect($result)->toHaveKey('test', 'https://test.example.com');
});

it('returns correct APP_URL for .env.staging', function () {
    $dotenvMock = app(Dotenv::class);
    
    $dotenvMock->shouldReceive('createArrayBacked')
        ->with(base_path(), '.env.staging')
        ->andReturnSelf()
        ->shouldReceive('safeLoad')
        ->andReturn(['APP_URL' => 'https://staging.example.com']);
    
    $action = app(YourEnvProcessingAction::class);
    $result = $action->handle(['staging']);
    
    expect($result)->toHaveKey('staging', 'https://staging.example.com');
});

3. 批量模拟多文件场景

如果需要一次性处理多个.env文件,可多次调用shouldReceive指定不同参数的返回逻辑:

it('handles multiple env files correctly', function () {
    $dotenvMock = app(Dotenv::class);
    
    // 模拟.test文件
    $dotenvMock->shouldReceive('createArrayBacked')
        ->with(base_path(), '.env.test')
        ->andReturnSelf()
        ->shouldReceive('safeLoad')
        ->andReturn(['APP_URL' => 'https://test.example.com'])
        ->once();
    
    // 模拟.staging文件
    $dotenvMock->shouldReceive('createArrayBacked')
        ->with(base_path(), '.env.staging')
        ->andReturnSelf()
        ->shouldReceive('safeLoad')
        ->andReturn(['APP_URL' => 'https://staging.example.com'])
        ->once();
    
    $action = app(YourEnvProcessingAction::class);
    $result = $action->handle(['test', 'staging']);
    
    expect($result)->toEqual([
        'test' => 'https://test.example.com',
        'staging' => 'https://staging.example.com'
    ]);
});

关键注意事项

  • 确保Action通过依赖注入获取Dotenv实例,而非直接调用静态方法;如果是静态调用,需改用Mockery的静态模拟方式。
  • 测试结束后Mockery会自动清理实例,也可在afterEach中手动调用Mockery::close()避免残留。
  • 若需模糊匹配路径,可用Mockery::type('string')替代精确路径,比如with(Mockery::type('string'), '.env.test')。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 12:30:12