2017-02-20 96 views
2

Laravel的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('/'); 

     // ... 
    } 
} 

但是,我有一些我想用于测试的种子数据。如果我运行:

php artisan migrate --seed 

然后它适用于第一个测试,但它失败后续测试。这是因为特征回滚了迁移,并且当它再次运行迁移时,它不会为数据库创建种子。我如何在迁移中运行数据库种子?

回答

11

我花了一些时间来解决这个问题,所以I thought I'd share

如果你看一下在DatabaseMigrations trait的源代码,然后你会看到它有一个功能runDatabaseMigrations多数民众赞成由setUpruns 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

下面是一个替代的解决方案,如果你喜欢绕过Artisan的天然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); 
    } 

}