Laravel 5为测试之间的单元测试重新接种数据库 [英] Laravel 5 Reseeding the Database for Unit Testing Between Tests
问题描述
我从种子数据库开始,并试图在单元测试之间在Laravel 5中重新设定数据库。在Laravel 4中,我理解你可以简单地使用Illuminate \Support \Facades\Artisan并运行命令
I start with a seeded database and am trying to reseed the database between unit tests in Laravel 5. In Laravel 4 I understand you could simply use Illuminate\Support\Facades\Artisan and run the commands
Artisan :: call('migrate');
Artisan :: call('db:seed');
Artisan::call('migrate'); Artisan::call('db:seed');
或者你应该可以做:
$ this-> seed('DatabaseSeeder');
$this->seed('DatabaseSeeder');
。在Laravel 5中,这似乎已被替换为
before every test. In Laravel 5 this appears to have been replaced by
使用DatabaseMigrations;
或
使用DatabaseTransactions;
use DatabaseMigrations; or use DatabaseTransactions;
我已经尝试使用这些并已成功地进行测试迁移数据库;然而,它实际上不对表中的数据重新设定种子。我已经读过几个论坛抱怨这个,并尝试了几种不同的方法调用这些从TestCase和内部每个测试...添加
I have tried using these and have managed to get the tests to migrate the database; however, it doesn't actually reseed the data in the tables. I have read through several forums complaining about this and have tried several different approaches calling these from the TestCase and inside every Test...adding the
$this->beforeApplicationDestroyed(function () {
Artisan::call('migrate');
Artisan::call('migrate:reset');
Artisan::call('db:seed');
DB::disconnect();
});
到TestCase.php中的tearDown()...
to the TestCase.php tearDown()...
我也试过添加
$this->createApplication();
到TestCase.php的每个测试中调用的方法
to a method called in every test from TestCase.php
有时它只是擦掉我的表完全。我在Laravel的网站或博客找到的没有什么似乎工作。部分原因可能是因为我可能在Laravel 5上尝试Laravel 4方法。在Laravel 5中有什么办法吗?
Sometimes it just wipes my tables out completely. Nothing I am finding on Laravel's site or in blogs seems to work. Part of it is probably because I'm probably trying Laravel 4 methods in Laravel 5. Is there any way to do this in Laravel 5?
我的代码用于测试用例。 php看起来像:
My code for the testcase.php looks like:
<?php
use Illuminate\Support\Facades\Artisan as Artisan;
class TestCase extends Illuminate\Foundation\Testing\TestCase{
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
protected $baseUrl = 'http://localhost';
public function initializeTests(){
$this->createApplication();
Artisan::call('migrate');
$this->artisan('migrate');
Artisan::call('db:seed');
$this->artisan('db:seed');
$this->seed('DatabaseSeeder');
$this->session(['test' => 'session']);
$this->seed('DatabaseSeeder');
}
public function tearDown()
{
Mockery::close();
Artisan::call('migrate:reset');
$this->artisan('migrate:reset');
Artisan::call('migrate:rollback');
$this->artisan('migrate:rollback');
Artisan::call('migrate');
$this->artisan('migrate');
Artisan::call('db:seed');
$this->artisan('db:seed');
$this->seed('DatabaseSeeder');
DB::disconnect();
foreach (\DB::getConnections() as $connection) {
$connection->disconnect();
}
$this->beforeApplicationDestroyed(function () {
Artisan::call('migrate:reset');
$this->artisan('migrate:reset');
Artisan::call('migrate:rollback');
$this->artisan('migrate:rollback');
Artisan::call('migrate');
$this->artisan('migrate');
Artisan::call('db:seed');
$this->artisan('db:seed');
$this->seed('DatabaseSeeder');
DB::disconnect();
foreach (\DB::getConnections() as $connection) {
$connection->disconnect();
}
});
$this->flushSession();
parent::tearDown();
}
public function getConnection()
{
$Connection = mysqli_connect($GLOBALS['DB_DSN'], $GLOBALS['DB_USERNAME'], $GLOBALS['DB_PASSWORD'], $GLOBALS['DB_DATABASE']);
$this->createDefaultDBConnection();
return $this->Connection;
}
public function createApplication()
{
$app = require __DIR__.'/../bootstrap/app.php';
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
return $app;
}
/**
* Magic helper method to make running requests simpler.
*
* @param $method
* @param $args
* @return \Illuminate\Http\Response
*/
public function __call($method, $args)
{
if (in_array($method, ['get', 'post', 'put', 'patch', 'delete']))
{
return $this->call($method, $args[0]);
}
throw new BadMethodCallException;
}
/**
* Create a mock of a class as well as an instance.
*
* @param $class
* @return \Mockery\MockInterface
*/
public function mock($class)
{
$mock = Mockery::mock($class);
$this->app->instance($class, $mock);
return $mock;
}
}
我的测试看起来像
My Test looks something like
<?php
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Artisan;
class CustomerRegistrationControllerTest extends TestCase
{
use DatabaseMigrations;
protected static $db_inited = false;
protected static function initDB()
{
echo "\n---Customer Registration Controller Tests---\n"; // proof it only runs once per test TestCase class
Artisan::call('migrate');
Artisan::call('db:seed');
}
public function setUp()
{
parent::setUp();
if (!static::$db_inited) {
static::$db_inited = true;
static::initDB();
}
// $this->app->refreshApplication();
$this->artisan('migrate:refresh');
$this->seed();
$this->seed('DatabaseSeeder');
$this->initializeTests();
);
}
public function testSomething()
{
$this->Mock
->shouldReceive('destroy')
->with('1')
->andReturn();
$this->RegistrationController->postRegistration();
// $this->assertResponseStatus(200);
}
}
推荐答案
只需执行此操作:
$this->artisan('migrate:refresh', [
'--seed' => '1'
]);
为了避免对测试之间的数据库进行更改add 使用DatabaseTransactions
到你的数据库测试。
To avoid changes to the database persisting between tests add use DatabaseTransactions
to your tests that hit the database.
这篇关于Laravel 5为测试之间的单元测试重新接种数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!