我有一个类getPaginatedQuery
,它的第一步是立即克隆其中一个参数:
public function getPaginatedQuery(Builder $query, $limit = null, $offset = null)
{
$constrainedQuery = clone $query;
...
}
Builder
对象的克隆是通过其__clone
魔术方法完成的。
我试图通过为Builder
传递一个模拟的$query
实例来对此方法进行单元测试:
$query = m::mock('Illuminate\Database\Eloquent\Builder');
$relation->getPaginatedQuery($query, 2, 1);
我的测试因致命错误而失败:__clone method called on non-object
。我已尝试在__clone
对象上定义$query
的期望,但我得到同样的错误:
$query = m::mock('Illuminate\Database\Eloquent\Builder');
$clonedQuery = m::mock('Illuminate\Database\Eloquent\Builder');
$query->shouldReceive('__clone')->andReturn($clonedQuery);
$relation->getPaginatedQuery($query, 2, 1);
我在这里做错了什么?
答案 0 :(得分:0)
Eloquent\Builder
实际上包含(作为成员)Query\Builder
的实例,其魔法__clone
方法在此基础clone
对象上调用Query\Builder
:< / p>
/**
* Force a clone of the underlying query builder when cloning.
*
* @return void
*/
public function __clone()
{
$this->query = clone $this->query;
}
由于你在嘲笑Eloquent\Builder
,它实际上并没有一个潜在的$this->query
成员,因为它会在Eloquent\Builder
的构造函数中设置,它永远不会被完全调用嘲笑对象。
要解决此问题,您需要创建Eloquent\Builder
的部分模拟,并使用模拟的Query\Builder
实例告诉run its real constructor:
$baseQuery = m::mock('Illuminate\Database\Query\Builder');
$query = m::mock('Illuminate\Database\Eloquent\Builder', [$baseQuery])->makePartial();
$relation->getPaginatedQuery($query, 2, 1);
现在,在clone $query
中调用getPaginatedQuery()
时,模拟的Eloquent\Builder
实例将能够在上调用clone
模拟Query\Builder
实例。