0

Eloquent メソッドにアクセスしたり使用したりできない場合、PHPSpec を使用する意味は何ですか?

例: ($this は EloquentProductモデルを参照します)

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

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

これはメソッド内では機能せず、さまざまな Eloquent CollectionaddPropertyおよびModel 関数への呼び出しがあります。これらすべてのクラスがステートメントremovePropertyに含まれている場合でも、PHPSpec はこれを処理できないようです。use

Laracasts の Jeffery Way のスクリーン キャストで、彼が実際の Eloquent モデルを使用していないことに気付きました。彼はバニラの PHP オブジェクトのみを使用します。それのポイントは何ですか?それは現実の世界ではありません。

また、私はすでにこれを行っているため、雄弁なモデルクラスを正しく参照することとは関係ありませんuse Illuminate\Database\Eloquent\Model;

また、私はファサードを決して使用しません。だから、そうでもありません。

4

1 に答える 1

3

PHPSpec は、たとえば PHPUnit や Mockery で実行できる多くのことを実行できません。
結論: PHPSpec は Eloquent をテストするための適切なツールではないと思います。

Eloquent の内部では多くの「魔法」が起こっており、PHPSpec は魔法を好まないようです。Eloquent をテストするために PHPSpec を使用する必要があると感じた場合、そうしないと世界が粉々になってしまうと感じた場合は、次の 2 つの方法を実行できます。

免責事項: Eloquent のテストに PHPSpec を使用することを推奨しているわけではありません。実際、PHPSpec を使用して雄弁なモデルをテストすることは望ましくありません。魔法のメソッドのテスト中に遭遇する状況を回避するためのいくつかのトリックを説明しているだけです。そしてブラックアート-それが理にかなっているときに他の場所に適用できることを願って. 私には、Eloquent モデルの場合は意味がありません。

リストは次のとおりです。

  • 魔法のゲッターとセッターを使用せずgetAttribute()setAttribute()代わりにand を使用してください
  • 遅延ロードされたリレーションにマジック コールを使用しないでください$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
}

whereおとりクラスでandメソッドを定義しlatestて SUT にすることで、これらのメソッドが実際にクラスに存在することを PHPSpec に知らせます。それらの引数と戻り値の型は重要ではなく、存在のみが重要です。

アドバンテージ ?
これで、仕様でモデルの呼び出し->where()または->latest()メソッドを実行しても、PHPSpec はそれについて文句を言うことはありません。おとりクラスのメソッドを変更して、たとえばオブジェクトを返し、それに対してProphecyアサーションを行うことができます。

于 2014-12-16T10:01:03.927 に答える