[英]Setting up PHPUnit tests in Laravel
我對單元測試很新,但我已經閱讀了很多關於phpunit.de的文檔(直到第10章)。
它指出使用數據庫進行測試可能很慢,但如果設置正確,它可以與非數據庫測試一樣快。
因此,我想在Laravel中測試一個模型。 我已經創建了一個模型工廠來將數據植入數據庫。
我也創建了一個基本測試。
在PHPUnits文檔中,它聲明在每次測試之前,調用setUp()
方法來設置測試。 還有另一個靜態方法setUpBeforeClass()
。
我想只為我的數據庫表播種一次,並使用我的測試中的記錄。 所以我使用Laravels factory()
函數從setUpBeforeClass()
方法中為數據庫設定種子。
這是我的代碼:
class CommentTest extends TestCase
{
protected static $blog;
protected static $comments;
public static function setUpBeforeClass()
{
parent::setUpBeforeClass();
self::$blog = factory(App\Models\Content\Blog::class)->create();
self::$comments = factory(App\Models\Content\Comment::class, 6)->create();
}
public function testSomething()
{
$this->assertTrue(true);
}
}
但是,當我運行phpunit
,我收到以下錯誤:
Fatal error: Call to a member function make() on a non-object in \vendor\laravel\framework\src\Illuminate\Foundation\helpers.php on line 54
Call Stack:
0.0002 240752 1. {main}() \vendor\phpunit\phpunit\phpunit:0
0.0173 1168632 2. PHPUnit_TextUI_Command::main() \vendor\phpunit\phpunit\phpunit:47
0.0173 1175304 3. PHPUnit_TextUI_Command->run() \vendor\phpunit\phpunit\src\TextUI\Command.php:100
2.9397 5869416 4. PHPUnit_TextUI_TestRunner->doRun() \vendor\phpunit\phpunit\src\TextUI\Command.php:149
2.9447 6077272 5. PHPUnit_Framework_TestSuite->run() \vendor\phpunit\phpunit\src\TextUI\TestRunner.php:440
2.9459 6092880 6. PHPUnit_Framework_TestSuite->run() \vendor\phpunit\phpunit\src\Framework\TestSuite.php:747
2.9555 6096160 7. call_user_func:{\vendor\phpunit\phpunit\src\Framework\TestSuite.php:697}() \vendor\phpunit\phpunit\src\Framework\TestSuite.php:697
2.9555 6096272 8. CommentTest::setUpBeforeClass() \vendor\phpunit\phpunit\src\Framework\TestSuite.php:697
2.9555 6096480 9. factory() \tests\CommentTest.php:18
2.9556 6096656 10. app() \vendor\laravel\framework\src\Illuminate\Foundation\helpers.php:350
如果我將代碼從setUpBeforeClass()
移動到setUp()
並運行它,它會按預期工作,但這肯定是低效的,因為它為每個測試播種數據庫?
我的問題:
setUpBeforeClass()
播種數據庫的正確方法嗎? factory()
之前我應該做些什么? setUp()
方法中,是否會出現性能問題? setUpBeforeClass()
或setUp()
方法中播種? 在Laravels文檔中,它顯示了在測試中發生種子的示例,但是如果我正在運行100次測試(例如),播種100次是個好主意嗎? 好的,經過一些調查(類)后,我確定在調用靜態setUpBeforeClass()
方法時尚未創建Laravel應用程序。
Laravel容器是在第一次在\\vendor\\laravel\\framework\\src\\illuminate\\Foundation\\Testing\\TestCase.php
調用setUp()
時創建的。 這就是我將代碼移動到setUp()
方法時工作正常的原因。
然后將容器存儲在存儲在\\vendor\\laravel\\framework\\src\\illuminate\\Foundation\\Testing\\ApplicationTrait.php
中的$app
屬性中。
我可以通過將此代碼添加到setUpBeforeClass()
方法來手動創建容器實例:
$app = require __DIR__.'/../bootstrap/app.php';
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
但是這種方法看起來很糟糕,我不喜歡它。
相反,我將種子代碼移動到setUp
()方法,但只有在類屬性為null時才播種數據庫。 因此它只會在第一次調用setUp()
時播種。 任何后續電話都不會播種:
class CommentTest extends TestCase
{
use DatabaseMigrations;
protected static $blog;
protected static $comments;
public function setUp()
{
parent::setUp();
$this->runDatabaseMigrations();
if (is_null(self::$blog)) {
self::$blog = factory(App\Models\Content\Blog::class, 1)->create();
self::$comments = factory(App\Models\Content\Comment::class, 6)->create();
}
}
}
結合Laravels DatabaseMigrations
特性進行測試,現在是工作流程:
DatabaseMigrations
特征 setUp()
方法,該方法使用測試數據對相關表進行種子處理 tearDown()
方法,而DatabaseMigrations
特性只是重置數據庫,因此我的測試不必擔心清理測試數據。 編輯
此外,似乎(雖然我不是100%),如果你有一個自定義setUp()
方法,你需要從重寫的setUp()
方法手動調用runDatabaseMigrations()
:
public function setUp()
{
parent::setUp();
$this->runDatabaseMigrations();
/** Rest of Setup **/
}
如果重載setUp()
方法,似乎不會自動調用runDatabaseMigrations()
。
我希望這會有所幫助,但如果其他人有更好的解決方案,請隨時告訴我:)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.