Testing in Laravel (P2)

Tiếp nối với bài viết lần trước Testing in Laravel , bài viết lần này mình sẽ trình bày tiếp vê phần Database Testing trong Laravel. Nội dung bài viết được tham khảo trên trang https://laravel.com/docs/5.3/database-testing.

I. Giới thiệu.

  • Laravel cung cấp một loạt công cụ hữu ích hỗ trợ cho việc kiểm thử dữ liệu trong ứng dụng của bạn. Đầu tiên bạn có thể sử dụng helper seeInDatabase để kiểm tra sự tồn tại giá trị trong database. Ví dụ, bạn muốn kiểm thử bảng users với trường email có giá trị là [email protected] bạn có thể làm như sau:

    public function testDatabase()
    {
        // Make call to application...

        $this->seeInDatabase('users', [
            'email' => '[email protected]'
        ]);
    }
  • Tất nhiên, phương thức seeInDatabase và các helper khác là dễ dàng sử dụng. Bạn có thể sử dụng bất kỳ phương thức nào trong PHPUnit để hỗ trợ việc kiểm thử.

II. Resetting The Database After Each Test

  • Nó là dễ dàng để thiết lập lại cơ sở dữ liệu của bạn sau mỗi lần kiểm thử mà không bị ảnh hưởng đến dữ liệu trong phần kiểm thử tiếp theo.

1. Using Migrations

  • Một biện pháp để thiết lập lại trạng thái cơ sở dữ liệu là rollback dữ liệu sau khi kiểm thử và migrate nó trước khi thực hiện kiểm thử tiếp theo. Laravel cung cấp DatabaseMigrations để tự động xử lý vấn đề đó một cách đơn giản.
    <?php

    use Illuminate\Foundation\Testing\WithoutMiddleware;
    use Illuminate\Foundation\Testing\DatabaseMigrations;
    use Illuminate\Foundation\Testing\DatabaseTransactions;

    class ExampleTest extends TestCase
    {
        use DatabaseMigrations;

        /**
         * A basic functional test example.
         *
         * @return void
         */
        public function testBasicExample()
        {
            $this->visit('/')
                 ->see('Laravel 5');
        }
    }

2. Using Transactions

  • Một cách khác để thiết lập lại trạng thái cơ sở dữ liệu là thực hiện mỗi một thử nghiệm trong một cơ sở dữ liệu. Như vậy thì khá phức tạp, một lần nữa Laravel lại cung cấp một giải pháp tối ưu đó là sử dụng DatabaseTransactions.
    <?php

    use Illuminate\Foundation\Testing\WithoutMiddleware;
    use Illuminate\Foundation\Testing\DatabaseMigrations;
    use Illuminate\Foundation\Testing\DatabaseTransactions;

    class ExampleTest extends TestCase
    {
        use DatabaseTransactions;

        /**
         * A basic functional test example.
         *
         * @return void
         */
        public function testBasicExample()
        {
            $this->visit('/')
                 ->see('Laravel 5');
        }
    }

III. Using Factories

1. Creating Model

  • Một khi bạn đã định nghĩa được các factory của bạn, bạn có thể sử dụng function factory trong các kiểm thử của bạn để tạo ra các trường hợp model. Vì vậy, chúng ta hãy xem xét một vài trường hợp tạo ra các model. Đầu tiên, chúng ta sử dụng phương thức make để tạo model nhưng không lưu chúng vào cơ sở dữ liệu.
    public function testDatabase()
    {
        $user = factory(App\User::class)->make();

        // Use model in tests...
    }
  • Bạn cũng có thể tạo ra một bộ sưu tập các model hoặc tạo ra các model của một kiểu nhất định như sau:
    // Create three App\User instances...
    $users = factory(App\User::class, 3)->make();
  • Applying States: bạn cũng có thể áp dụng bất kỳ trạng thái của bạn vào model. Nếu bạn muốn áp dụng nhiều trạng thái vào model, bạn nên xác định tên mỗi trạng thái mà bạn áp dụng:
    $users = factory(App\User::class, 5)->states('delinquent')->make();

    $users = factory(App\User::class, 5)->states('premium', 'delinquent')->make();
  • Overriding Attributes: Nếu bạn muốn ghi đề lên một số giá trị mặc định của model,bạn có thể truyển một mảng giá trị thông qua phương thức make. Chỉ các giá trị đặc biệt sẽ được thay thế trong khi phần còn lại của giá trị sẽ được thiết lập theo quy định của factory.
    $user = factory(App\User::class)->make([
        'name' => 'Abigail',
    ]);

2. Persisting Models

  • Phương thức create không chỉ tạo mà còn lưu chúng vào cơ sở dữ liệu bằng cách sử dụng phương thức save của Eloquent.
    public function testDatabase()
    {
        // Create a single App\User instance...
        $user = factory(App\User::class)->create();

        // Create three App\User instances...
        $users = factory(App\User::class, 3)->create();

        // Use model in tests...
    }
  • Bạn có thể các thuộc tính trên model bằng cách truyền một mảng tới phương thức create:
    $user = factory(App\User::class)->create([
        'name' => 'Abigail',
    ]);

3. Relationships

  • Trong ví dụ này, chúng ta sẽ đính kèm một quan hệ trong một vào model đã tạo. Khi sử dụng phương thức create để tạo nhiều model, một tập hợp Eloquent được trả lại,cho phép sử dụng bất kỳ chức năng tiện lợi nào, ví dụ như function each:
    $users = factory(App\User::class, 3)
               ->create()
               ->each(function ($u) {
                    $u->posts()->save(factory(App\Post::class)->make());
                });
  • Relations & Attribute Closures: Bạn có thể đính kèm relationships tới các model sử dụng thuộc tính relationships định nghĩa trong factory của bạn. Ví dụ, nếu bạn muốn tạo một user mới trong khi đang tạo bài viết bạn có thể làm như sau:
    $factory->define(App\Post::class, function ($faker) {
        return [
            'title' => $faker->title,
            'content' => $faker->paragraph,
            'user_id' => function () {
                return factory(App\User::class)->create()->id;
            }
        ];
    });
  • Closures cũng nhận mảng các thuộc tính của factory bao gồm:
    $factory->define(App\Post::class, function ($faker) {
        return [
            'title' => $faker->title,
            'content' => $faker->paragraph,
            'user_id' => function () {
                return factory(App\User::class)->create()->id;
            },
            'user_type' => function (array $post) {
                return App\User::find($post['user_id'])->type;
            }
        ];
    });

All Rights Reserved