【问题标题】:Mocking Illuminate\Database\Eloquent\Model模拟 Illuminate\Database\Eloquent\Model
【发布时间】:2013-08-04 17:52:36
【问题描述】:

我需要用 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);
    }
}

【问题讨论】:

    标签: phpunit laravel eloquent mockery


    【解决方案1】:

    如果没有“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”实际上只是在实例化的 eloquent 模型上调用“get”。

    【讨论】:

    • 在测试方法$mockModel = Mockery::mock('\Ekrmbk\Post')做了一个快速编辑...否则你不能$mockModel->shouldReceive
    猜你喜欢
    • 2021-04-20
    • 2014-05-17
    • 1970-01-01
    • 2014-11-29
    • 2018-10-22
    • 2023-03-13
    • 2019-06-22
    • 2021-10-25
    • 2022-10-16
    相关资源
    最近更新 更多