Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking Illuminate\Database\Eloquent\Model

I need to mock Laravel's Eloquent\Model with Mockery and it is kind of tricky because it uses static methods.

I solved this issue with the following code but I wonder if there is a better/smarter way to do this.

<?php

use Ekrembk\Repositories\EloquentPostRepository;

class EloquentPostRepositoryTest extends TestCase {
    public function __construct()
    {
        $this->mockEloquent = Mockery::mock('alias:Ekrembk\Post');
    }

    public function tearDown()
    {
        Mockery::close();
    }

    public function testTumuMethoduEloquenttenAldigiCollectioniDonduruyor()
    {
        $eloquentReturn = 'fake return';
        $this->mockEloquent->shouldReceive('all')
                     ->once()
                     ->andReturn($eloquentDongu);
        $repo = new EloquentPostRepository($this->mockEloquent);

        $allPosts = $repo->all();
        $this->assertEquals($eloquentReturn, $allPosts);
    }
}
like image 272
ekrembk Avatar asked Apr 26 '26 14:04

ekrembk


1 Answers

Tough to tell without the source of "Ekrembk\Repositories\EloquentPostRepository", but, I see a couple of issues. It looks like within your EloquentPostRepository, you're calling a static. You shouldn't do that. It makes it hard to test (as you've discovered). Assuming that Ekrembk\Post extends from Eloquent, you can do this instead:

<?php 
namespace Ekrembk\Repositories

class EloquentPostRepository {

    protected $model;

    public __construct(\Ekrembk\Post $model) {
        $this->model = $model;
    }   

    public function all()
    {
        $query = $this->model->newQuery();

        $results = $query->get();

        return $results;
    }

}

Then, your test will be simpler:

<?php

use Ekrembk\Repositories\EloquentPostRepository;

class EloquentPostRepositoryTest extends TestCase {

    public function tearDown()
    {
        Mockery::close();
    }

    public function testTumuMethoduEloquenttenAldigiCollectioniDonduruyor()
    {
        $mockModel = Mockery::mock('\Ekrembk\Post');
        $repo = new EloquentPostRepository($mockModel);
        $eloquentReturn = 'fake return';

        $mockModel->shouldReceive('newQuery')->once()->andReturn($mockQuery = m::mock(' \Illuminate\Database\Eloquent\Builder'));

        $result = $mockQuery->shouldReceive('get')->once()->andReeturn($eloquentReturn);

        $this->assertEquals($eloquentReturn, $result);
    }
}

Didn't test the above so it might have issues, but you should get the idea.

If you look in Illuminate\Database\Eloquent\Model, you'll see that "public static function all" is really just calling "get" on an instantiated eloquent model.

like image 117
awei Avatar answered Apr 29 '26 12:04

awei



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!