Okay, so I'm trying to move one of my packages over to PHPSpec tests, but soon I ran into this problem. The packages is a shoppingcart package, so I want to test that when you add two items to the cart, the cart has a count of two, simple. But of course, in a shoppingcart, when adding two of the same items, there will not be a new entry in the cart, but the original item will get a 'qty' of 2. So but not when they are, for instance, different sizes. So each item is identified by a unique rowId, based on it's ID and options.
This is the code that generates the rowId (which is used by the add()
method):
protected function generateRowId(CartItem $item)
{
return md5($item->getId() . serialize($item->getOptions()));
}
Now I had written my test like this:
public function it_can_add_multiple_instances_of_a_cart_item(CartItem $cartItem1, CartItem $cartItem2)
{
$this->add($cartItem1);
$this->add($cartItem2);
$this->shouldHaveCount(2);
}
But the problem is, both stubs return null
for the getId()
method. So I tried setting the willReturn()
for that method, so my test became this:
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);
}
But now I get errors, telling me that unexpected methods are called like getName()
. So I have to do the same for all methods on the CartItem interface that are called:
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);
}
Now this works, test is green. But it feels wrong... Am I missing something or is this a limitation on PHPSpec?
Yeah you can call that "limitation" of phpspec. Basically phpspec is strict TDD and object communication design tool IMO.
You see that adding $cartItem to collection do much more that you expects.
First one you do not have to use stubs (if you don't care about internal object communication) example:
You can do it other way as well. From communication perspective query many times same instance of object is not so effective. Many public methods mean many different combinations. You can plan communication and do something like that: