[英]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.