我在测试方面完全是个新手,我想知道是否有人可以指导我做错了什么。我想在我的php laravel项目中测试以下函数:
public static function getFlatSupplierAddress($supplier_address_id): string
{
$supplierAddress = Address::findOrFail($supplier_address_id);
return $supplierAddress->street . " " .
$supplierAddress->number . " " .
$supplierAddress->apartment . ", " .
($supplierAddress->city ? $supplierAddress->city->name : '') . ", " .
($supplierAddress->province ? $supplierAddress->province->name : '') . ", " .
($supplierAddress->country ? $supplierAddress->country->name : '');
}
这是我的测试代码:
it('returns the formatted supplier address', function () {
$addressMock = Mockery::mock(Address::class);
$addressMock->shouldReceive('findOrFail')
->with(1)
->andReturnSelf(); // Retorna el mismo mock
$addressMock->shouldReceive('getAttribute')
->with('street')
->andReturn('Calle');
$addressMock->shouldReceive('getAttribute')
->with('number')
->andReturn('456');
$addressMock->shouldReceive('getAttribute')
->with('apartment')
->andReturn('Apt 789');
$addressMock->shouldReceive('city')
->andReturn((object)['name' => 'Retiro']);
$addressMock->shouldReceive('province')
->andReturn((object)['name' => 'Buenos Aires']);
$addressMock->shouldReceive('country')
->andReturn((object)['name' => 'Argentina']);
$expectedAddress = 'Calle 456 , Retiro, Buenos Aires, Argentina';
$formattedAddress = AddressService::getFlatSupplierAddress(1);
// Assert
expect($formattedAddress)->toBe($expectedAddress);
当然,我有一个问题,我没有很好地使用Mock,因为函数返回给我一个在数据库中找到的地址字符串,并将其与我创建的Mock进行比较。
1条答案
按热度按时间kkih6yb81#
你不需要嘲笑任何东西来测试它
编辑更深入的解释
正如我所评论的,
findOrFail
实际上不是Address
中的方法。Laravel经常这么做。它通过使用__call
或__callStatic
将调用转发到后台的其他类。当执行
Address::findOrFail(1)
时,它实际上调用了底层Illuminate\Database\Eloquent\Model
的静态__callStatic('findOrFail', [1])
。...这反过来又做了
(new static)->findOrFail(1)
.它依次调用
Model
的__call('findOrFail' [1])
.它最终调用
Model
的newQuery()
并返回Illuminate\Database\Eloquent\Builder
。... whichfinallycalls
findOrFail(1)
.而这仅仅涵盖了
findOrFail
。无论何时调用Model
的属性($address->street
、$address->city->name
等),它都会通过__call
将调用转发给其他方法。如果你真的想用mocks来写这个测试,并确保它不接触数据库,我想你可以写这样的东西:
顺便说一句,如果你想测试
Address
中有或没有City
,Province
和Country
的每一个组合,那就是8个不同的情况。您可以利用按位操作来避免编写8次相同的测试。或者,如果您不关心写入测试数据库