我刚刚开始使用PHPSpec,我真的非常喜欢PHPUnit,特别是那些不费力的模拟和存根。无论如何,我正在尝试测试的方法需要一组Cell
个对象。我怎么能告诉PHPSpec给我一系列嘲笑?
我班级的简化版
<?php
namespace Mything;
class Row
{
/** @var Cell[] */
protected $cells;
/**
* @param Cell[] $cells
*/
public function __construct(array $cells)
{
$this->setCells($cells);
}
/**
* @param Cell[] $cells
* @return Row
*/
public function setCells(array $cells)
{
// validate that $cells only contains instances of Cell
$this->cells = $cells;
return $this;
}
}
我测试的简化版
<?php
namespace spec\MyThing\Row;
use MyThing\Cell;
use PhpSpec\ObjectBehavior;
class RowSpec extends ObjectBehavior
{
function let()
{
// need to get an array of Cell objects
$this->beConstructedWith($cells);
}
function it_is_initializable()
{
$this->shouldHaveType('MyThing\Row');
}
// ...
}
我曾希望我能做到以下几点,但它却抱怨找不到Cell[]
。使用FQN,它抱怨无法找到\MyThing\Cell[]
。
/**
* @param Cell[] $cells
*/
function let($cells)
{
// need to get an array of Cell objects
$this->beConstructedWith($cells);
}
我能解决的唯一选择是传递多个类型提示的Cell
参数并手动将它们组合成一个数组。我错过了一些简单的东西吗?
编辑:我正在使用PHPSpec 2.5.3,不幸的是服务器目前停留在PHP 5.3: - (
答案 0 :(得分:1)
为什么不做
之类的事情use Prophecy\Prophet;
use Cell; // adapt it with PSR-4 and make it use correct class
class RowSpec extends ObjectBehavior
{
private $prophet;
private $cells = [];
function let()
{
$this->prophet = new Prophet();
for ($i = 0; $i < 10; $i++) {
$this->cells[] = $this->prophet->prophesize(Cell::class);
}
$this->beConstructedWith($cells);
}
// ....
function letGo()
{
$this->prophet->checkPredictions();
}
public function it_is_a_dummy_spec_method()
{
// use here your cells mocks with $this->cells
// and make predictions on them
}
}
在let
函数中,您实例化一个Prophet
对象,它基本上是一个与PHPSpec(它本身使用Prophecy)一起使用的模拟库/框架。
我建议保留实例($this->prophet
),这对后续步骤很有用。
现在,你必须创建你的模拟,你可以使用prophet
和prophesize
。
即使对于模拟,我建议将它们保存为一个私有变量,你可能用于方法中的预测。
letGo
函数可以明确检查您对cells
的期望:不,cells
仅为stubs
或dummies
。
当然,通过方法签名模拟并明确跳过checkPredictions
很方便,但是,只要你需要一系列模拟,我想这是达到你的唯一方法目标