【问题标题】:PHPSpec and LaravelPHPSpec 和 Laravel
【发布时间】:2014-12-15 17:27:46
【问题描述】:

如果我无法访问或使用任何 Eloquent 方法,那么使用 PHPSpec 有什么意义?

例如:($this 指的是 Eloquent Product 模型)

function it_removes_property(PropertyValueInterface $property)
{        
    $this->addProperty($property);
    $this->properties->shouldHaveCount(1);

    $this->removeProperty($property);
    $this->properties->shouldHaveCount(0);
} 

这将不起作用,因为在 addPropertyremoveProperty 方法中调用了各种 Eloquent Collection 和 Model 函数,似乎 PHPSpec 无法处理这个问题,即使所有这些类都包含在 use 语句中。

我注意到 Jeffery Way 在 Laracasts 上的屏幕投射中,他从不使用真正的 Eloquent 模型。他只使用普通的 PHP 对象。那有什么意义呢?那不是真实的世界。

这也与正确引用 eloquent 模型类无关,因为我已经在这样做了use Illuminate\Database\Eloquent\Model;

我也从不使用外墙。所以它也不是。

【问题讨论】:

    标签: php testing laravel bdd phpspec


    【解决方案1】:

    PHPSpec 不能做很多你可以做的事情,例如,使用 PHPUnit 和 Mockery。
    底线:我会说 PHPSpec 不是测试 Eloquent 的正确工具。 em>

    Eloquent 内部发生了很多'魔法',而 PHPSpec 似乎并不喜欢魔法,如果你觉得你必须使用 PHPSpec 来测试 Eloquent,否则世界将会崩溃,那么这里是你可以做几件事。

    免责声明: 我不鼓励你继续使用 PHPSpec 进行 Eloquent 测试,实际上我不希望你用它来测试 eloquent 模型,我只是解释一些解决您在测试魔法方法和黑艺术时遇到的情况的技巧 - 希望您能够在有意义的时候将它们应用到其他地方。对我来说,这对于 Eloquent 模型没有意义。

    所以这里是列表:

    • 不要使用魔法 getter 和 setter,而是使用 getAttribute()setAttribute()
    • 不要对延迟加载的关系使用魔术调用,即$user->profile。使用方法$user->profile()->getResults()
    • 创建一个 SUT 模拟类来扩展您的模型并在其上定义那些 where 方法,同时定义范围方法以及 Eloquent 应该为您“神奇地”做的所有事情。
    • 使用beAnInstanceOf() 方法切换到模拟并对其进行断言。

    下面是我的测试的示例:

    产品型号

    use Illuminate\Database\Eloquent\Model;    
    
    class Product extends Model
    {
        public function scopeLatest($query)
        {
            return $query->where('created_at', '>', new Carbon('-1 week'))
                ->latest();
        }
    
        // Model relations here...
    }
    

    产品型号规格

    <?php namespace Spec\Model;
    
    use Prophecy\Argument;
    use App\Entities\Product;
    use PhpSpec\ObjectBehavior;
    
    class ProductSpec extends ObjectBehavior
    {
        public function let()
        {
            $this->beAnInstanceOf(DecoyProduct::class);
        }
    
        public function it_is_initializable()
        {
            $this->shouldHaveType('Product');
        }
    }
    
    // Decoy Product to run tests on
    class DecoyProduct extends Product
    {
        public function where();
    
        // Assuming the Product model has a scope method
        // 'scopeLatest' on it that'd translate to 'latest()'
        public function latest();
    
        // add other methods similarly
    }
    

    通过在诱饵类上定义wherelatest 方法并将其设为SUT,您可以让PHPSpec 知道这些方法实际上存在于该类中。它们的参数和返回类型无关紧要,重要的是存在。

    优势?
    现在在您的规范中,当您在模型上调用 -&gt;where()-&gt;latest() 方法时,PHPSpec 不会抱怨它,您可以更改诱饵类上的方法以返回,例如,Prophecy 的对象并对其进行断言.

    【讨论】:

      猜你喜欢
      • 2015-08-25
      • 2021-11-08
      • 2015-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-20
      • 1970-01-01
      相关资源
      最近更新 更多