Setting up PHPUnit tests in Laravel(在 Laravel 中设置 PHPUnit 测试)
问题描述
我对单元测试还很陌生,但我已经阅读了几乎所有关于 phpunit.de 的文档(直到第 10 章).
它指出使用数据库进行测试可能会很慢,但如果设置正确,它可以与非数据库测试一样快.
因此,我想在 Laravel 中测试一个模型.我创建了一个模型工厂来将数据播种到数据库中.
我还创建了一个基本测试.
在 PHPUnits 文档中,它声明在每次测试之前,都会调用 setUp() 方法来设置测试.还有另外一个静态方法
setUpBeforeClass()
.
我只想为我的数据库表播种一次,并在我的测试中使用这些记录.所以我使用 Laravel 的 factory()
函数从 setUpBeforeClass()
方法中为数据库播种.
这是我的代码:
class CommentTest 扩展了 TestCase{受保护的静态 $blog;受保护的静态 $comments;公共静态函数 setUpBeforeClass(){父::setUpBeforeClass();self::$blog = factory(AppModelsContentBlog::class)->create();self::$comments = factory(AppModelsContentComment::class, 6)->create();}公共函数 testSomething(){$this->assertTrue(true);}}
但是,当我运行 phpunit
时,出现以下错误:
致命错误:在第 54 行对 vendorlaravelframeworksrcIlluminateFoundationhelpers.php 中的非对象调用成员函数 make()调用堆栈:0.0002 240752 1. {main}() vendorphpunitphpunitphpunit:00.0173 1168632 2. PHPUnit_TextUI_Command::main() vendorphpunitphpunitphpunit:470.0173 1175304 3. PHPUnit_TextUI_Command->run() vendorphpunitphpunitsrcTextUICommand.php:1002.9397 5869416 4. PHPUnit_TextUI_TestRunner->doRun() vendorphpunitphpunitsrcTextUICommand.php:1492.9447 6077272 5. PHPUnit_Framework_TestSuite->run()vendorphpunitphpunitsrcTextUITestRunner.php:4402.9459 6092880 6. PHPUnit_Framework_TestSuite->run()vendorphpunitphpunitsrcFrameworkTestSuite.php:7472.9555 6096160 7. call_user_func:{vendorphpunitphpunitsrcFrameworkTestSuite.php:697}()vendorphpunitphpunitsrcFrameworkTestSuite.php:6972.9555 6096272 8. CommentTest::setUpBeforeClass() vendorphpunitphpunitsrcFrameworkTestSuite.php:6972.9555 6096480 9. factory() estsCommentTest.php:182.9556 6096656 10.app()vendorlaravelframeworksrcIlluminateFoundationhelpers.php:350
如果我将代码从 setUpBeforeClass()
移动到 setUp()
并运行它,它会按预期工作,但这肯定是低效的,因为它为数据库播种每次测试?
我的问题:
- 在
setUpBeforeClass()
中为数据库播种是正确的方法吗? - 如果是(问题1),那么为什么我在运行phpunit时会遇到致命错误,在调用
factory()
之前我应该做什么? - 如果我必须将代码放在
setUp()
方法中,是否会出现性能问题? - 我什至应该从
setUpBeforeClass()
或setUp()
方法中播种吗?在 Laravel 文档中,它显示了在测试本身中进行播种的示例,但如果我正在运行 100 个测试(例如),那么播种 100 次是个好主意吗?
好的,经过一番调查(类),我确定 Laravel 应用程序在静态 setUpBeforeClass()
方法被调用.
Laravel 容器是在 vendorlaravelframeworksrcilluminateFoundationTestingTestCase.php
中第一次调用 setUp()
时创建的.这就是为什么当我将代码移动到 setUp()
方法时它可以正常工作的原因.
容器然后存储在 vendorlaravelframeworksrcilluminateFoundationTestingApplicationTrait.php
中的 $app
属性中..p>
我可以通过将此代码添加到 setUpBeforeClass()
方法来手动创建容器实例:
$app = 需要 __DIR__.'/../bootstrap/app.php';$app->make(IlluminateContractsConsoleKernel::class)->bootstrap();
但是这种方法看起来很hacky,我不喜欢它.
相反,我将播种代码移至 setUp
() 方法,但仅在类属性为空时才播种数据库.因此,它只会在第一次调用 setUp()
时播种.任何后续调用都不会被播种:
class CommentTest 扩展了 TestCase{使用数据库迁移;受保护的静态 $blog;受保护的静态 $comments;公共函数设置(){父::setUp();$this->runDatabaseMigrations();if (is_null(self::$blog)) {self::$blog = factory(AppModelsContentBlog::class, 1)->create();self::$comments = factory(AppModelsContentComment::class, 6)->create();}}}
结合 Laravel 的 DatabaseMigrations
trait 进行测试,现在的工作流程如下:
- PHPUnit 被调用
- Test 类被调用,其中包含
DatabaseMigrations
trait - 迁移数据库(创建表)
- 第一次调用
setUp()
方法,用测试数据播种相关表 - 运行测试,并访问测试数据
- 没有调用
tearDown()
方法,而是DatabaseMigrations
trait 只是简单地重置数据库,所以我的测试不必担心清理测试数据.
编辑
另外,看起来(虽然我不是100%),如果你有自定义的setUp()
方法,你需要手动调用runDatabaseMigrations()
从重写的 setUp()
方法:
公共函数 setUp(){父::setUp();$this->runDatabaseMigrations();/** 其余设置 **
本文标题为:在 Laravel 中设置 PHPUnit 测试
基础教程推荐
- 通过 PHP SoapClient 请求发送原始 XML 2021-01-01
- XAMPP 服务器不加载 CSS 文件 2022-01-01
- 在多维数组中查找最大值 2021-01-01
- 在 Woocommerce 中根据运输方式和付款方式添加费用 2021-01-01
- 超薄框架REST服务两次获得输出 2022-01-01
- mysqli_insert_id 是否有可能在高流量应用程序中返回 2021-01-01
- 在 PHP 中强制下载文件 - 在 Joomla 框架内 2022-01-01
- Libpuzzle 索引数百万张图片? 2022-01-01
- WooCommerce 中选定产品类别的自定义产品价格后缀 2021-01-01
- 如何在 PHP 中的请求之间持久化对象 2022-01-01