PHPSpec和Laravel

时间:2014-12-15 17:27:47

标签: php testing laravel bdd phpspec

如果我无法访问或使用任何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无法处理这个问题,即使所有这些类都包含在{{{ 1}}陈述。

我注意到在Jeffery Way的Laracasts屏幕上,他从未使用真正的Eloquent模型。他只使用vanilla PHP对象。那是什么意思?那不是现实世界。

这也与正确引用eloquent模型类无关,因为我已经在做这个use

我从来没有永远使用外墙。所以它也不是。

1 个答案:

答案 0 :(得分:3)

PHPSpec无法做很多事情,例如PHPUnit和Mockery。
底线:我说PHPSpec不是测试Eloquent的正确工具。

在Eloquent中发生了很多' ,如果您认为必须使用PHPSpec测试Eloquent或PHPSpec似乎不喜欢魔法世界将破灭然后这里有几件你可以做的事情。

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

所以这是清单:

  • 不要使用魔法吸气剂和制定者,而是使用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知道这些方法实际存在于类中。他们的论点和回归类型并不重要,只有存在。

优势?
现在在您的规范中,当您在模型上调用->where()->latest()方法时,PHPSpec将不会抱怨它,您可以更改decoy类上的方法以返回{{1}的对象并在其上做出断言。