如何在Laravel中使用Mockery模拟StripeClient类的构造函数
Laravel中Mockery模拟StripeClient(带构造参数)的解决方案
在Laravel单元测试中使用Mockery模拟StripeClient时,若通过app(StripeClient::class, ['config' => $key])初始化客户端,会触发真实构造函数执行(导致无效密钥错误),即使尝试模拟__construct也无效。但不传构造参数时模拟正常。
问题根源
当调用app(Class::class, $parameters)时,Laravel容器会忽略已绑定的实例,而是尝试用传入的参数重新实例化原始类,因此之前绑定的mock不会被使用。
解决方案1:构造Mock时指定匹配的构造参数
直接在创建Mockery实例时传入构造参数,确保容器解析时匹配并使用该mock:
// 创建带构造参数匹配的StripeClient mock $stripeMock = \Mockery::mock(StripeClient::class, ['config' => $this->stripeSecretKey]); // 模拟request方法(对应balance->retrieve的底层调用) $stripeMock->shouldReceive('request') ->zeroOrMoreTimes() ->andReturn([ 'available' => [ 'amount' => 1000, ], 'livemode' => false, ]); // 将mock绑定到Laravel容器 $this->app->instance(StripeClient::class, $stripeMock);
解决方案2:使用Laravel测试助手mock()(Laravel 8+)
利用Laravel内置的测试助手简化mock流程,同时处理构造参数:
$this->mock(StripeClient::class, function ($mock) { // 允许模拟构造函数,匹配传入的config参数 $mock->makePartial()->shouldReceive('__construct') ->with(['config' => $this->stripeSecretKey]) ->andReturnSelf(); // 模拟request方法返回预期数据 $mock->shouldReceive('request') ->zeroOrMoreTimes() ->andReturn([ 'available' => [ 'amount' => 1000, ], 'livemode' => false, ]); });
更优方案:依赖注入替代app()助手调用
修改服务类,通过构造函数依赖注入StripeClient,避免直接在代码中调用app(),让测试更灵活:
修改服务类
class StripeService { protected $stripeClient; // 构造函数注入StripeClient public function __construct(StripeClient $stripeClient) { $this->stripeClient = $stripeClient; } public function getStripeBalance(string $stripeAccountId): array { return $this->stripeClient ->balance ->retrieve([], ['stripe_account' => $stripeAccountId]) ->toArray(); } }
测试代码
// 创建mock并设置预期行为 $stripeMock = \Mockery::mock(StripeClient::class); $stripeMock->shouldReceive('request') ->zeroOrMoreTimes() ->andReturn([ 'available' => ['amount' => 1000], 'livemode' => false, ]); // 直接将mock注入服务类 $stripeService = new StripeService($stripeMock); $balance = $stripeService->getStripeBalance('acc_123456'); // 断言结果符合预期 $this->assertEquals(1000, $balance['available'][0]['amount']);
内容的提问来源于stack exchange,提问作者Gaurav Deshpande
相关产品推荐
相关产品推荐

