Какой смысл использовать PHPSpec, если я не могу получить доступ или использовать какие-либо методы Eloquent?
Например: ($ это относится к Eloquent Product
модель)
function it_removes_property(PropertyValueInterface $property)
{
$this->addProperty($property);
$this->properties->shouldHaveCount(1);
$this->removeProperty($property);
$this->properties->shouldHaveCount(0);
}
Это не будет работать как в методах addProperty
а также removeProperty
есть вызовы к различным функциям Eloquent Collection и Model, кажется, что PHPSpec не может справиться с этим, даже если все эти классы включены в use
заявления.
Я заметил в скриншотах Джеффри Уэя на Laracasts, что он никогда не использует настоящую модель Eloquent. Он использует только ванильные объекты PHP. Какой смысл в этом? Это не реальный мир.
Также это не имеет ничего общего с правильной ссылкой на класс модели eloquent, поскольку я уже делаю это use Illuminate\Database\Eloquent\Model;
Также я НИКОГДА никогда не использую фасады. Так что это тоже не то.
PHPSpec не способен делать много вещей, которые вы можете делать, например, с помощью PHPUnit и Mockery.
Итог: я бы сказал, что PHPSpec не подходит для тестирования Eloquent.
Имеется много «Волшебный» что происходит внутри Eloquent, и PHPSpec, похоже, не любит магию, если вам кажется, что вы должны использовать PHPSpec для тестирования Eloquent, или мир рухнет, вот пара вещей, которые вы можете сделать.
Отказ от ответственности: Я не призываю вас идти вперед и использовать PHPSpec для Eloquent тестирования, на самом деле я не хочу, чтобы вы тестировали красноречивые модели с ним, я лишь объясняю некоторые приемы, чтобы обойти ситуации, с которыми вы столкнетесь при тестировании магических методов и черного искусство — в надежде, что вы сможете применить их где-то еще, когда это имеет смысл. Для меня это не имеет смысла в случае Eloquent моделей.
Итак, вот список:
getAttribute()
а также setAttribute()
вместо$user->profile
, Использовать методы $user->profile()->getResults()
where
методы для него, также определяют методы области видимости и все остальное, что Eloquent должен сделать для вас «волшебным образом».beAnInstanceOf()
способ переключиться на макет и сделать на нем утверждения.Вот пример того, как мой тест будет выглядеть:
Модель продукта
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
public function scopeLatest($query)
{
return $query->where('created_at', '>', new Carbon('-1 week'))
->latest();
}
// Model relations here...
}
Спецификация для модели продукта
<?php namespace Spec\Model;
use Prophecy\Argument;
use App\Entities\Product;
use PhpSpec\ObjectBehavior;
class ProductSpec extends ObjectBehavior
{
public function let()
{
$this->beAnInstanceOf(DecoyProduct::class);
}
public function it_is_initializable()
{
$this->shouldHaveType('Product');
}
}
// Decoy Product to run tests on
class DecoyProduct extends Product
{
public function where();
// Assuming the Product model has a scope method
// 'scopeLatest' on it that'd translate to 'latest()'
public function latest();
// add other methods similarly
}
Определяя where
а также latest
метод в классе-ловушке и делая его SUT, вы даете PHPSpec знать, что эти методы действительно существуют в классе. Их аргументы и тип возвращаемого значения не имеют значения, только существование.
Преимущество?
Теперь в вашей спецификации, когда вы звоните ->where()
или же ->latest()
Метод в модели PHPSpec не будет жаловаться на это, и вы можете изменить методы класса-ловушки, чтобы он возвращал, скажем, объект Prophecy
и сделать на нем утверждения.
Других решений пока нет …