Cri*_*ane 1 php testing mocking phpspec stubs
好的,所以我试图将我的一个软件包移到PHPSpec测试中,但很快我遇到了这个问题.这些包是一个购物车包,所以我想测试一下,当你向购物车添加两个商品时,购物车的数量为2,简单.不过,当然,在一个购物车,增加了两个相同的项目的时候,不会有在车一个新的条目,但原来的项目将得到的2"数量"所以,而不是当他们是,例如,不同的尺寸.因此,每个项目都由唯一的rowId标识,基于它的ID和选项.
这是生成rowId的代码(由add()方法使用):
protected function generateRowId(CartItem $item)
{
return md5($item->getId() . serialize($item->getOptions()));
}
Run Code Online (Sandbox Code Playgroud)
现在我写了这样的测试:
public function it_can_add_multiple_instances_of_a_cart_item(CartItem $cartItem1, CartItem $cartItem2)
{
$this->add($cartItem1);
$this->add($cartItem2);
$this->shouldHaveCount(2);
}
Run Code Online (Sandbox Code Playgroud)
但问题是,两个存根都返回null该getId()方法.所以我尝试设置willReturn()for该方法,所以我的测试成了这样:
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);
}
Run Code Online (Sandbox Code Playgroud)
但现在我得到错误,告诉我意外的方法被称为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);
}
Run Code Online (Sandbox Code Playgroud)
现在这个工作,测试是绿色的.但感觉不对......我错过了什么或者这是对PHPSpec的限制吗?
小智 9
现在这个工作,测试是绿色的.但感觉不对......我错过了什么或者这是对PHPSpec的限制吗?
我认为在这种情况下感觉不错是因为它应该.正如上面提到的@ l3l0,PHPSpec是一个设计工具,它为您提供了有关您的设计的明确信息.
你挣扎的事实是你Cart违反了单一责任原则 - 它不止一件事 - 它管理CartItems并知道如何从中生成RowId.因为PHPSpec强制你存在CartItem它的整个行为,它会给你一个消息来重构生成RowId.
现在假设你将RowIdGenerator提取为单独的类(这里没有涉及它自己的规范):
class RowIdGenerator
{
public function fromCartItem(CartItem $item)
{
return md5($item->getId() . serialize($item->getOptions()));
}
}
Run Code Online (Sandbox Code Playgroud)
然后通过构造函数将此生成器作为依赖项注入到Cart中:
class Cart
{
private $rowIdGenerator;
public function __construct(RowIdGenerator $rowIdGenerator)
{
$this->rowIdGenerator = $rowIdGenerator;
}
}
Run Code Online (Sandbox Code Playgroud)
然后你的最终规格可能如下:
function let(RowIdGenerator $rowIdGenerator)
{
$this->beConstructedWith($rowIdGenerator);
}
public function it_can_add_multiple_instances_of_a_cart_item(RowIdGenerator $rowIdGenerator, CartItem $cartItem1, CartItem $cartItem2)
{
$rowIdGenerator->fromCartItem($cartItem1)->willReturn('abc');
$rowIdGenerator->fromCartItem($cartItem1)->willReturn('def');
$this->add($cartItem1);
$this->add($cartItem2);
$this->shouldHaveCount(2);
}
Run Code Online (Sandbox Code Playgroud)
而且因为你嘲笑了id生成器的行为(并且你知道这种通信必须发生),所以现在你遵守了SRP.你现在觉得好些吗?
| 归档时间: |
|
| 查看次数: |
2010 次 |
| 最近记录: |