使用嘲弄模拟和存根相同的 class 实例

Mocking and stubbing the same class instance using mockery

我有一个 class 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 数据替换。

在mock expectations 运行之前如何使用stub数据?

因为这里要加上andReturn:

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

在这种情况下,最好 return 嘲笑 CollectionCollection