2013-08-03 5 views
2

Мне нужно высмеять Laravel's Eloquent \ Model с Mockery, и это довольно сложно, потому что использует статические методы.Mocking Illuminate Database Eloquent Model

Я решил эту проблему со следующим кодом, но мне интересно, есть ли лучший/более умный способ сделать это.

<?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); 
    } 
} 

ответ

2

Сложно сказать без источника «Ekrembk \ Хранилища \ EloquentPostRepository», но я вижу несколько проблем. Похоже, что в вашем EloquentPostRepository вы вызываете статику. Вы не должны этого делать. Это затрудняет тестирование (как вы обнаружили). Предполагая, что Ekrembk \ Post простирается от красноречивых, вы можете сделать это вместо:

<?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; 
    } 

} 

Тогда, ваш тест будет проще:

<?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); 
    } 
} 

не тестировал выше, так что могут возникнуть проблемы, но вы должны получить эту идею.

Если вы посмотрите в Illuminate \ Database \ Eloquent \ Model, вы увидите, что «public static function all» на самом деле просто вызывает «get» на экземплярной красноречивой модели.

+0

Это умный способ решить эту проблему. Благодаря! – ekrembk

+0

сделал быстрое редактирование в методе тестирования '$ mockModel = Mockery :: mock ('\ Ekrmbk \ Post')' ... иначе вы не можете $ mockModel-> shouldReceive – awei

Смежные вопросы