Reputation: 490
I'm testing one of my controllers and no matter what I try I get the error that the all()
function doesn't exist.
Static method Mockery_1_App_Models_User::all() does not exist on this mock object
My test method:
/**
* Test index page
* @return void
*/
public function testIndexAsUser()
{
$this->beUser();
// The method calls the mock objects should receive
$this->user->shouldReceive('all')->once()->andReturn([]);
// Call index page
$response = $this->call('GET', 'users');
// Assertions
$this->assertResponseOk();
$this->assertViewHas('user');
$this->assertViewNameIs('users.show');
}
My mocking method:
/**
* Mock a class
* @param string $class
* @return Mockery
*/
public function mock($class)
{
$mock = Mockery::mock('Eloquent', $class);
app()->instance($class, $mock);
return $mock;
}
My actual controller method:
/**
* Show all users
* @return Response
*/
public function getIndex()
{
$users = $this->user->all();
return view('users.index');
}
Am I using the wrong Eloquent class in my mock object or something? Since Laravel 5 the models are not referring to Eloquent but to Illuminate\Database\Eloquent\Model
but I've tried that too.
Upvotes: 4
Views: 5084
Reputation: 8029
The easiest way to mock an Eloquent model is by using partials:
$mock = m::mock('MyModelClass')->makePartial();
However, it won't help you much as you're using a static method (all()
). PHP's not-so-strict nature lets you call static methods in a non-static way ($user->all()
), but you should avoid it. Instead you should do it the heavy-handed way:
$users = $this->user->newQuery()->get();
This can be mocked:
$mockUser->shouldReceive('newQuery->get')->andReturn([/*...*/]);
If you want to take this one step further, move the get()
call into a separate repository class that is injected into the controller, which will make it easier to mock. You can find plenty of articles on the repository pattern online.
Upvotes: 3