Mocking Illuminate \ Database \ Eloquent \ Model

时间:2013-08-03 15:03:19

标签: phpunit laravel eloquent mockery

我需要使用Mockery模拟Laravel的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);
    }
}

1 个答案:

答案 0 :(得分:4)

在没有“Ekrembk \ Repositories \ EloquentPostRepository”来源的情况下告诉我,但是,我看到了一些问题。它看起来像在你的EloquentPostRepository中,你正在调用静态。你不应该这样做。它使测试变得困难(正如您所发现的那样)。假设Ekrembk \ Post从Eloquent扩展,你可以这样做:

<?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”。