I have a class myModel which makes database calls. 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.
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.
How can the stub data be used before the mock expectations are run?
Because you have to add andReturn here:
$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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With