使用mockery模拟和存根同一个类实例

时间:2016-10-20 11:56:53

标签: php laravel mockery

我有一个类myModel来进行数据库调用。因此,我想将其存根,以便它实际上不会进行任何这些昂贵的调用。

public function myFunction($limit)
{
    $this->doThing();
}

private function doThing()
{
    $result = $this->myModel
        ->select('thing')
        ->groupBy('name')
        ->orderBy('count', 'desc')
        ->get;

    // do stuff with $result
}

因此,对我进行调用的模型方法进行存根

/** @test */
public function my_test()
{
    $stuff = new Collection(['person1', 'person2', 'person3',]);

    $myModelMock = m::mock(MyModel::class, [
        'select->groupBy->orderBy->get' => $stuff
    ]);

    App::instance(MyModel::class, $myModelMock);
    $myOtherClass = App::make(OtherClassWhereMyModelIsInjectedAutomagically::class);

    $myOtherClass->myFunction();
}

哪个效果很好,输出$result作为我在测试中定义的$stuff的集合。

但是,我还想确保流畅的界面功能仅调用一次。我理解这些函数是在私有方法中调用的,但这并不重要,因为我没有测试私有函数本身。

所以当我尝试使用

/** @test */
public function query_ran_once()
{
    $stuff = new Collection(['person1', 'person2', 'person3',]);

    $myModelMock = m::mock(MyModel::class, [
        'select->groupBy->orderBy->get' => $stuff,
        'where->update' => null,
        'whereIn->update' => null
    ]);

    $myModelMock
        ->shouldReceive('select->groupBy->orderBy->get')
        ->times(1)

    App::instance(MyModel::class, $myModelMock);
    $myOtherClass = App::make(OtherClassWhereMyModelIsInjectedAutomagically::class);

    $myOtherClass->myFunction();
}

我收到一个错误,最终导致$resultnull - 这意味着我的测试中的$stuff数据不再被替换。

如何在模拟期望运行之前使用存根数据?

1 个答案:

答案 0 :(得分:2)

因为你必须在这里添加andReturn

$collection = m::mock(\Illuminate\Database\Eloquent\Collection::class)
$myModelMock
    ->shouldReceive('select->groupBy->orderBy->get')
    ->times(1)
    ->andReturn($collection);

在这种情况下,最好返回模拟的CollectionCollection