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

Laravel中如何无需创建工厂模拟带构造参数的外部类做单元测试?

简化Laravel中ReCaptcha/Mailchimp的依赖注入与测试

一、移除冗余工厂类,直接绑定到容器

你之前为处理构造参数创建了工厂类,其实可以直接在AppServiceProvider里把带参数的类绑定到Laravel容器,省去工厂类和额外配置:

// App\Providers\AppServiceProvider.php
public function register()
{
    // 绑定ReCaptcha,自动注入配置的密钥
    $this->app->bind(\ReCaptcha\ReCaptcha::class, function ($app) {
        return new \ReCaptcha\ReCaptcha(config('services.recaptcha.secret'));
    });

    // 同理处理Mailchimp(根据它的构造参数调整)
    $this->app->bind(\NZTim\Mailchimp\Mailchimp::class, function ($app) {
        return new \NZTim\Mailchimp\Mailchimp(config('services.mailchimp.api_key'));
    });
}

之后控制器里直接通过容器获取实例,或者用依赖注入更规范:

// 方式1:直接从容器获取
$recaptcha = app(\ReCaptcha\ReCaptcha::class);

// 方式2:构造函数依赖注入(推荐)
public function __construct(private \ReCaptcha\ReCaptcha $recaptcha) {}

// 方法内直接调用
$this->recaptcha->verify(...);

二、简化单元测试的模拟逻辑

原来的测试需要模拟make方法,现在容器直接返回实例,测试里只需要模拟业务方法即可:

$mock_response = // 提前准备的模拟响应对象
$this->mock(\ReCaptcha\ReCaptcha::class, function ($mock) use ($mock_response) {
    $mock->shouldReceive('verify')
        ->once()
        ->andReturn($mock_response);
});

三、关于你提到的resolve传参方式

你说的resolve(ReCaptcha::class, ['param1'=>config('services.recaptcha.secret')])是可行的,但这种方式需要每次调用都手动传参数,适合临时创建实例的场景。如果业务代码中频繁使用,还是推荐容器绑定的方式,更简洁且符合Laravel的依赖注入规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 23:40:15