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

Laravel中如何用PHPUnit和Mockery断言服务构造函数参数

解决方案

要验证ServiceOne调用testOne时是否向ServiceTwo的构造函数传入了正确参数,你可以采用以下两种可靠方案:

方案1:通过容器绑定回调捕获并验证参数

直接借助Laravel容器的绑定回调机制,在解析ServiceTwo时捕获传入的参数并执行断言:

public function testServiceOnePassesCorrectNameToServiceTwo()
{
    $expectedName = 'testing';

    // 构建ServiceTwo的Mock,仅验证testTwo方法被调用一次
    $serviceTwoMock = \Mockery::mock(ServiceTwo::class)
        ->shouldReceive('testTwo')
        ->once()
        ->getMock();

    // 绑定ServiceTwo到容器,回调中捕获参数并断言
    $this->app->bind(ServiceTwo::class, function ($app, $parameters) use ($serviceTwoMock, $expectedName) {
        $this->assertEquals($expectedName, $parameters['name'], 'ServiceTwo构造函数的name参数不符');
        return $serviceTwoMock;
    });

    // 执行测试方法
    app(ServiceOne::class)->testOne($expectedName);
}

当ServiceOne调用app(ServiceTwo::class, ['name' => $name])时,容器会将传入的参数数组传递给绑定回调的$parameters变量,此时即可直接验证参数的准确性。若参数不符合预期,断言会立即失败并给出明确提示。

方案2:使用Mockery构造函数参数验证

利用Mockery的shouldBeConstructedWith方法,直接指定ServiceTwo实例化时必须接收的参数:

public function testServiceOnePassesCorrectNameToServiceTwo()
{
    $expectedName = 'testing';

    // 创建Mock时,同时验证构造函数参数和testTwo方法调用
    $serviceTwoMock = \Mockery::mock(ServiceTwo::class)
        ->shouldBeConstructedWith([$expectedName])
        ->shouldReceive('testTwo')
        ->once()
        ->getMock();

    // 将Mock实例绑定到容器
    $this->app->instance(ServiceTwo::class, $serviceTwoMock);

    // 执行测试方法
    app(ServiceOne::class)->testOne($expectedName);
}

该方案会直接验证Mock被构造时是否传入了预期参数。如果ServiceOne传入的参数错误,Mockery会抛出断言失败异常,终止测试。

关键说明

  • 方案1更灵活,支持对参数进行复杂验证(比如正则匹配、类型检查等);方案2更简洁,直接利用Mockery的内置断言能力。
  • 确保测试类中已正确引入Mockery,且在测试完成后清理Mock(Laravel项目的测试基类通常会在tearDown方法中自动执行Mockery::close())。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 00:52:19