简体   繁体   English

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

[英]Mocking and stubbing the same class instance using mockery

I have a class myModel which makes database calls. 我有一个myModel类来进行数据库调用。 As such I want to stub this so it doesn't actually make any of these expensive calls. 因此我希望将其存根,以便它实际上不会进行任何这些昂贵的调用。

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

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

    // do stuff with $result
}

So to stub the models methods which make the call I use 因此,对我使用的调用的模型方法进行存根

/** @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();
}

Which works perfectly, outputting $result as the Collection of $stuff I define in the test. 哪个工作完美,输出$result作为我在测试中定义的$stuff的集合。

However, I also want to ensure that the fluent interface functions are only called once . 但是,我还想确保只调用一次流畅的接口函数。 I understand these functions are being called inside a private method but that shouldn't matter as I am not testing the private function itself. 我理解这些函数是在私有方法中调用的,但这并不重要,因为我没有测试私有函数本身。

So when I try and use 所以当我尝试使用时

/** @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();
}

I get an error which ends up being that $result is null - which means it is no longer being replaced by the $stuff data in my test. 我得到一个错误, $result$resultnull - 这意味着它不再被我测试中的$stuff数据替换。

How can the stub data be used before the mock expectations are run? 如何在模拟期望运行之前使用存根数据?

Because you have to add andReturn here: 因为你必须在这里添加和andReturn

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

In this case it's good to return mocked Collection or Collection . 在这种情况下,返回模拟的CollectionCollection是很好的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM