Laravel中PEST测试Address静态函数的Mock使用问题求助
问题分析与解决方案
你的Mock无效的核心原因是:你创建的是Address类的实例Mock,但getFlatSupplierAddress中调用的是静态方法Address::findOrFail(),这个静态调用不会关联到你创建的Mock实例,所以代码仍然会去查询真实数据库。
下面提供两种可行的解决方法:
方法一:Mock静态方法(直接解决当前Mock问题)
直接MockAddress类的静态findOrFail方法,让它返回你预先配置好属性的Mock实例:
it('returns the formatted supplier address', function () { // 创建Address实例Mock并配置属性 $addressMock = Mockery::mock(Address::class); $addressMock->street = 'Calle'; $addressMock->number = '456'; $addressMock->apartment = 'Apt 789'; $addressMock->city = (object)['name' => 'Retiro']; $addressMock->province = (object)['name' => 'Buenos Aires']; $addressMock->country = (object)['name' => 'Argentina']; // 关键:Mock静态方法findOrFail,让它返回我们的Mock实例 Address::shouldReceive('findOrFail') ->with(1) ->andReturn($addressMock); // 修正预期地址(原代码会拼接street/number/apartment三个字段) $expectedAddress = 'Calle 456 Apt 789, Retiro, Buenos Aires, Argentina'; $formattedAddress = AddressService::getFlatSupplierAddress(1); expect($formattedAddress)->toBe($expectedAddress); });
方法二:用测试数据替代Mock(更推荐新手)
如果不想用复杂的Mock逻辑,可以直接在测试数据库中创建真实的测试数据,验证函数的格式化逻辑:
it('returns the formatted supplier address', function () { // 创建关联的国家、省份、城市测试数据 $country = Country::factory()->create(['name' => 'Argentina']); $province = Province::factory()->create(['name' => 'Buenos Aires', 'country_id' => $country->id]); $city = City::factory()->create(['name' => 'Retiro', 'province_id' => $province->id]); // 创建地址测试数据 $address = Address::factory()->create([ 'street' => 'Calle', 'number' => '456', 'apartment' => 'Apt 789', 'city_id' => $city->id, 'province_id' => $province->id, 'country_id' => $country->id, ]); $expectedAddress = 'Calle 456 Apt 789, Retiro, Buenos Aires, Argentina'; $formattedAddress = AddressService::getFlatSupplierAddress($address->id); expect($formattedAddress)->toBe($expectedAddress); });
注意事项
- 需确保你已经为
Country/Province/City/Address创建了对应的Laravel模型工厂。 - 测试数据库建议使用SQLite内存库,避免污染真实数据。
- 原测试中的预期地址存在错误,函数会拼接
street/number/apartment三个字段,需修正后才能通过断言。
内容的提问来源于stack exchange,提问作者mushulmao
相关产品推荐
相关产品推荐

