2016-04-02 70 views
2

私はLaravel 5.2、phpunit 5.0.0、PHP 7.0.3を使っています。Eloquentモデルのスコープメソッドに触れるデータベースのやりとりを使ってテストを書こうとします。phpunitとMockeryを使ったLaravel 5.2のローカルスコープ

class Picture extends Illuminate\Database\Eloquent\Model { 
    ... 
    public function scopeGetPictureNameById($oQuery, $pictureHId) { 
     return $oQuery->select('name')->where('h_id', '=', $pictureHId)->first()->name; 
    } 
} 

class someHelperClass { 
    public function someMethod($pictureId) { 
     $pictureName = Picture::getPictureNameById($pictureId); 
     return "name is " . $pictureName; 
    } 
} 


class SomeTest extends TestCase { 

    use DatabaseMigrations; 

    protected $someHelper; 

    public function setUp() { 
     parent::setUp(); 
     $this->someHelper = new SomeHelper(); 
    } 

    /** 
    * @test 
    */ 
    public function someMethodTest() { 
     $expectedName = "test"; 
     $this->assertEquals("name is " . $expectedName, $this->someHelper->someMethod()); 
    } 
} 

私は名前を「テスト」に設定されている画像の記録でデータベースをシード:

は、私はそのようなものを持っています。

私が最初に思ったのは、スコープコールを嘲笑する必要がないということでした。必要なのはデータベースにあるからです。そして、私はテストの外で働いている(単純化されていない)コード以来、私はスコープコールはphpunitで動作しないと思います。 (「非オブジェクトのプロパティを取得しようとしています」という例外が表示されます)。オーケー

は、私は嘲笑して通話を模擬してみました:

class SomeTest extends TestCase { 

    use DatabaseMigrations; 

    protected $someHelper; 

    public function setUp() { 
     parent::setUp(); 
     $this->someHelper = new SomeHelper(); 
    } 

    /** 
    * @test 
    */ 
    public function someMethodTest() { 
     $expectedName = "test"; 

     $mockedPicture = Mockery::mock('overload:App\Models\Picture'); 
     $mockedPicture->shouldReceive('getPictureNameById')->andReturn('test'); 

     //also tried this: $mockedPicture->shouldReceive('scopeGetPictureNameById')->andReturn('test'); 


     $this->assertEquals("name is " . $expectedName, $this->someHelper->someMethod()); 
    } 
} 

私が得るすべては「モックのApp \モデル\画像をロードできませんでした、クラスがすでに存在している」です。ですから、どのようにしてPicture :: getPictureNameById($ pictureId)のようなクエリスコープコールを正しく模擬できますか?

答えて

1

静的にピクチャクラスのメソッドを呼び出す代わりに、依存関係注入を使用します。したがって、このような何か:あなたのテストで続いて

class someHelperClass { 

    protected $picture; 

    public function __construct(Picture $picture) { 
     $this->picture = $picture; 
    } 

    public function someMethod($pictureId) { 
     $pictureName = $this->picture->getPictureNameById($pictureId); 
     return "name is " . $pictureName; 
    } 
} 

:私はLaravelクエリスコープを使用してい

public function someMethodTest() { 
    $expectedName = "test"; 

    $mockedPicture = Mockery::mock('App\Models\Picture'); 
    $mockedPicture->shouldReceive('getPictureNameById')->andReturn('test'); 
    $someHelper = new SomeHelper($mockedPicture); 

    $this->assertEquals("name is " . $expectedName, $someHelper->someMethod(1)); 
} 
+0

(https://laravel.com/docs/5.1/eloquent#query-scopes)。どのように非静的に呼び出すことができますか? –

+0

私の例のように依存性注入を使用している場合、これを行うことができます。たぶん[この投稿](https://laracasts.com/discuss/channels/general-discussion/l5-facades-orpendency-injection)はそれを明確にします。あなたのために働かなかったのですか? –