2

関係を持つEloquentモデルに依存するクラスの単体テストを作成する最良の方法は何ですか? 例えば

  • 実オブジェクト (データベース付き)。これは簡単ですが、遅いです。

  • 実際のオブジェクト (データベースなし)。新しいオブジェクトを作成できますが、データベースに書き込まずに関連モデルを設定する方法がわかりません。

  • モック オブジェクト。Eloquent モデルで Mockery を使用すると問題が発生します (たとえば、この質問を参照してください)。

  • 他の解決策?

コンテキスト:アクセス制御にAuthority RBACでLaravelを使用しています。単体テストでアクセス ルールをテストする最適な方法を見つけたいと考えています。つまり、テスト中にユーザーの依存関係を Authority に渡す必要があります。

4

1 に答える 1

0

単体テストを作成している場合は、データベースを使用しないでください。データベースに対するテストは、統合テストと見なされます。Roy Osherove のビデオをご覧ください。

あなたの質問に答えるには、(権限RBACを掘り下げていないので、次のようにします:

// assuming some RBAC class
SomeRBACClass extends RBACBaseClass {

     function validate(UserClass $user) {
         if (!$roles = $user->getRoles())
         {
             return false;
         }

         $allowed = array('admin', 'superadmin');

         foreach ($roles as $role) {
             if (in_array($role->name, $allowed)) {
                 return true;
             }
         }

         return false;
     }

}

SomeRBACClassTest extends TestCase {

    function test_validate_WhenPassedUser_callsGetRolesOnUserWithNoArgs()
    {
        $rbac = new SomeRBACClass();
        $user = Mockery::mock('UserClass');

        $user->shouldReceive('getRoles')->once()->withNoArgs();

        $rbac->validate($user);
    }

    function test_validate_getRolesOnUserReturnsCollectionOfRoles_CallsGetAttributeWithNameOnFirstRole() {
        $rbac = new SomeRBACClass();
        $user = Mockery::mock('UserClass');
         // assuming $user->getRoles() returns a collection
        $collection = new \Illuminate\Support\Collection(array(
             $role1 = Mockery::mock('Role'),
             $role2 = Mockery::mock('Role'),
        ));
        $user->shouldReceive('getRoles')->andReturn($collection);

        $role1->shouldReceive('getAttribute')->once()->with('name');

        $rbac->validate($user);
    }

    function test_validate_getAttributeWithNameOnRoleReturnsValidRole_ReturnsTrue() {
        $rbac = new SomeRBACClass();
        $user = Mockery::mock('UserClass');
         // assuming $user->getRoles() returns a collection
        $collection = new \Illuminate\Support\Collection(array(
             $role1 = Mockery::mock('Role'),
             $role2 = Mockery::mock('Role'),
        ));
        $user->shouldReceive('getRoles')->andReturn($collection);
        $role1->shouldReceive('getAttribute')->andReturn('admin');

        $result = $rbac->validate($user);

        $this->assertTrue($result);
    }

これは、私が作成するすべての単体テストの完全な例ではありませんが、出発点です。たとえば、ロールが返されない場合、結果が false であることも検証します。

于 2014-04-18T23:06:35.490 に答える