Итак, я пытаюсь перенести один из моих пакетов на тесты PHPSpec, но вскоре я столкнулся с этой проблемой. Пакеты - пакет для покупок, поэтому я хочу проверить, что, когда вы добавляете два предмета в корзину, тележка имеет счет двух, простых. Но, конечно, в корзине покупок при добавлении двух одинаковых предметов в корзине не будет новой записи, но исходный элемент получит «qty» из 2. Так что, но не тогда, когда они есть, например , различные размеры. Таким образом, каждый элемент идентифицируется уникальным rowId на основе его идентификатора и опций.Откажитесь только от одного метода на заглушки PHPSpec
Это код, который генерирует RowId (который используется методом add()
):
protected function generateRowId(CartItem $item)
{
return md5($item->getId() . serialize($item->getOptions()));
}
Теперь я написал мой тест, как это:
public function it_can_add_multiple_instances_of_a_cart_item(CartItem $cartItem1, CartItem $cartItem2)
{
$this->add($cartItem1);
$this->add($cartItem2);
$this->shouldHaveCount(2);
}
Но проблема в том, оба заглушки возвращают null
для метода getId()
. Так что я попытался установить willReturn()
для этого метода, поэтому мой тест стал этим:
public function it_can_add_multiple_instances_of_a_cart_item(CartItem $cartItem1, CartItem $cartItem2)
{
$cartItem1->getId()->willReturn(1);
$cartItem2->getId()->willReturn(2);
$this->add($cartItem1);
$this->add($cartItem2);
$this->shouldHaveCount(2);
}
Но теперь я получаю ошибки, говоря мне, что неожиданные методы называются как getName()
. Так что я должен сделать то же самое для всех методов в интерфейсе CartItem, которые называются:
public function it_can_add_multiple_instances_of_a_cart_item(CartItem $cartItem1, CartItem $cartItem2)
{
$cartItem1->getId()->willReturn(1);
$cartItem1->getName()->willReturn(null);
$cartItem1->getPrice()->willReturn(null);
$cartItem1->getOptions()->willReturn([]);
$cartItem2->getId()->willReturn(2);
$cartItem2->getName()->willReturn(null);
$cartItem2->getPrice()->willReturn(null);
$cartItem2->getOptions()->willReturn([]);
$this->add($cartItem1);
$this->add($cartItem2);
$this->shouldHaveCount(2);
}
Сейчас это работает, тест зеленый. Но он чувствует себя не так ... Я что-то упустил или это ограничение на PHPSpec?
Интересный ответ, я уже «боялся», это было ограничение. Меня действительно не интересует внутренняя коммуникация объектов. Но причина, по которой мне нужны заглушки, - это то, что CartItem не является классом, а интерфейсом. Я хочу, чтобы люди могли использовать любой класс, который они хотят, до тех пор, пока они реализуют этот интерфейс. Поэтому я не могу просто создать экземпляр 'new CartItem()'. – Crinsane
Наличие геттеров и сеттеров и/или сумматоров в одном интерфейсе - не очень крутая идея;) Возможно, вы можете упростить интерфейс и сделать меньше методов. Вас может заинтересовать принцип разделения интерфейса. – l3l0
Как бы я это ни делал, я имею в виду, что все, о чем я забочусь, это то, что какой бы предмет, который кто-то пытается помещать в корзину, имеет имя, которое я могу получить, ID, который я могу получить, и т. Д. Поэтому мне нужны эти горстка геттеров ... Может быть, я вижу это неправильно, но для меня это имеет смысл. Мне все равно, какой тип объекта он есть, пока я могу получить идентификатор, имя, цену и параметры. :) – Crinsane