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

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);
});

注意事项

  1. 需确保你已经为Country/Province/City/Address创建了对应的Laravel模型工厂。
  2. 测试数据库建议使用SQLite内存库,避免污染真实数据。
  3. 原测试中的预期地址存在错误,函数会拼接street/number/apartment三个字段,需修正后才能通过断言。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 17:13:16