I am trying to Mock Eloquent Model with Mockery. Model is being injected in Controller via
__construct(Post $model){$this->model=$model}
Now I am calling the find()
function in controller
$post = $this->model->find($id);
And here is test for PostsController
class PostsTest extends TestCase{
protected $mock;
public function setUp() {
parent::setUp();
$this->mock = Mockery::mock('Eloquent', 'Posts'); /*According to Jeffrey Way you have to add Eloquent in this function call to be able to use certain methods from model*/
$this->app->instance('Posts', $this->mock);
}
public function tearDown() {
Mockery::close();
}
public function testGetEdit()
{
$this->mock->shouldReceive('find')->with(1)->once()->andReturn(array('id'=>1));
$this->call('GET', 'admin/posts/edit/1');
$this->assertViewHas('post', array('id'=>1));
}
}
Running PhpUnit gives me error:
Fatal error: Using $this when not in object context in ...\www\l4\vendor\mockery\mockery\library\Mockery\Generator.php(130) : eval()'d code on line 73
This is obviously because find()
is declared as static function. Now, the code works without errors, so how can I successfully mock Eloquent model without it failing. Since we are relying on dependency injection, I have to call find()
non-statically, otherwise I could just do Post::find()
.
One solution that I came up with is to create a non-static find()
replacement in BaseModel
public function nsFind($id, $columns = array('*'))
{
return self::find($id, $columns);
}
But this is a big pain as the function has to have different name!
Am I doing something wrong or do you have any better ideas?
Mocking Eloquent models is a very tricky thing. It's covered in the book, but I specifically note that it's a stop-gap. It's better to use repositories.
However, to answer your question, the issue is that you're not performing the mock within the constructor. That's the only way to get it to work. It's not ideal, and I wouldn't recommend it.
I think that is the reason, Jeffrey introduces Repositories in his book Laravel Testing Decoded (Chapter 10).
Mockery has a section about static methods in its README too, See https://github.com/padraic/mockery#mocking-public-static-methods
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