2017-02-20 4 views
2

Laravel's documentation рекомендует использовать признак DatabaseMigrations для переноса и возврата базы данных между тестами.Как переносить миграцию базы данных для тестов laravel?

use Illuminate\Foundation\Testing\DatabaseMigrations; 

class ExampleTest extends TestCase 
{ 
    use DatabaseMigrations; 

    /** 
    * A basic functional test example. 
    * 
    * @return void 
    */ 
    public function testBasicExample() 
    { 
     $response = $this->get('/'); 

     // ... 
    } 
} 

Однако у меня есть данные о семенах, которые я хотел бы использовать с моими испытаниями. Если я запустил:

затем он работает для первого испытания, но он не может выполнить последующие испытания. Это связано с тем, что этот признак откатывает миграцию, и когда он снова запускает миграцию, он не засевает базу данных. Как запустить семена базы данных с помощью миграции?

ответ

11

Мне потребовалось некоторое копание, чтобы понять это, поэтому I thought I'd share.

Если вы посмотрите на исходный код для DatabaseMigrations trait, то вы увидите, что она имеет одну функцию runDatabaseMigrations, которая вызывается с помощью setUp какой runs before every test и регистрирует функцию обратного вызова, которые будут работать на разборки.

Вы можете сортировать "extend" the trait путем сглаживания этой функции, повторно объявить новую функцию с вашей логикой в ​​ней (artisan db:seed) под первоначальным именем и вызвать псевдоним внутри нее.

use Illuminate\Foundation\Testing\DatabaseMigrations; 

class ExampleTest extends TestCase 
{ 
    use DatabaseMigrations { 
     runDatabaseMigrations as baseRunDatabaseMigrations; 
    } 

    /** 
    * Define hooks to migrate the database before and after each test. 
    * 
    * @return void 
    */ 
    public function runDatabaseMigrations() 
    { 
     $this->baseRunDatabaseMigrations(); 
     $this->artisan('db:seed'); 
    } 

    /** 
    * A basic functional test example. 
    * 
    * @return void 
    */ 
    public function testBasicExample() 
    { 
     $response = $this->get('/'); 

     // ... 
    } 
} 
+3

Это должно быть в документации тестирования! Посев может быть действительно важной частью тестирования, и я не видел упоминания об этом. поправьте меня если я ошибаюсь. –

+0

отличный ответ. Вот ярлык для документов для всех, кто интересуется, как создать сеялку: https://laravel.com/docs/5.6/seeding –

0

Вот альтернативное решение, в случае, если вы предпочитаете, чтобы обойти родную DatabaseMigrations ремесленника и методы сеялки/миграции. Вы можете создать свой собственный признак семян базы данных:

namespace App\Traits; 

use App\Models\User; 
use App\Models\UserType; 

trait DatabaseSetup 
{ 

    public function seedDatabase() 
    { 
     $user = $this->createUser(); 
    } 

    public function createUser() 
    { 
     return factory(User::class)->create([ 
      'user_type_id' => function() { 
       return factory(UserType::class)->create()->id; 
      } 
     ]); 
    } 

    public function getVar() { 
     return 'My Data'; 
    } 
} 

Затем вызовите его в тесте, как это:

use App\Traits\DatabaseSetup; 

class MyAwesomeTest extends TestCase 
{ 
    use DatabaseSetup; 
    use DatabaseTransactions; 

    protected $reusableVar; 

    public function setUp() 
    { 
     parent::setUp(); 
     $this->seedDatabase(); 
     $this->reusableVar = $this->getVar(); 
    } 

    /** 
    * @test 
    */ 
    public function test_if_it_is_working() 
    { 
     $anotherUser = $this->createUser(); 
     $response = $this->get('/'); 
     $this->seeStatusCode(200); 
    } 

} 
Смежные вопросы