[英]Laravel unit tests: redefinition error when running multiple test methods
I am trying to run a group of unit tests after reading an example here which require an active database connection. 我想读一个例子后运行一组单元测试这里需要一个活动的数据库连接。 It seems to work for one unit test, but it will fail with multiple tests due to redefinition of a constant contained in a Laravel Command
class. 它似乎适用于一个单元测试,但由于重新定义了Laravel Command
类中包含的常量,它将因多次测试而失败。 Here are the errors I receive after running PHP Unit: 以下是运行PHP单元后收到的错误:
PHPUnit 3.7.31 by Sebastian Bergmann.
FEE
Time: 203 ms, Memory: 5.00Mb
There were 2 errors:
1) MessageControllerTest::testSixMonths
ErrorException: Constant SHARE_SEND_EXPIRATION already defined
src/app/commands/DeleteExpiredSends.php:31
src/app/start/artisan.php:14
src/vendor/laravel/framework/src/Illuminate/Console/start.php:57
src/vendor/laravel/framework/src/Illuminate/Console/Application.php:30
src/vendor/laravel/framework/src/Illuminate/Foundation/Artisan.php:70
src/vendor/laravel/framework/src/Illuminate/Foundation/Artisan.php:45
src/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php:206
src/app/tests/MessageControllerTest.php:46
src/app/tests/MessageControllerTest.php:46
src/app/tests/MessageControllerTest.php:21
2) MessageControllerTest::testOneYear
ErrorException: Constant SHARE_SEND_EXPIRATION already defined
src/app/commands/DeleteExpiredSends.php:31
src/app/start/artisan.php:14
src/vendor/laravel/framework/src/Illuminate/Console/start.php:57
src/vendor/laravel/framework/src/Illuminate/Console/Application.php:30
src/vendor/laravel/framework/src/Illuminate/Foundation/Artisan.php:70
src/vendor/laravel/framework/src/Illuminate/Foundation/Artisan.php:45
src/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php:206
src/app/tests/MessageControllerTest.php:46
src/app/tests/MessageControllerTest.php:46
src/app/tests/MessageControllerTest.php:21
FAILURES!
Tests: 3, Assertions: 1, Errors: 2.
And here is my unit test: 这是我的单元测试:
<?php
class MessageControllerTest extends TestCase
{
/**
* setUp() : set up the unit tests by initializing the database
*/
public function setUp()
{
// call the parent's setup method
parent::setUp();
// init the DB
$this->migrateDatabase();
}
/**
* createApplication() : bootstrap the app in order to execute
* tests
*
* @return Symfony\Component\HttpKernel\HttpKernelInterface
*/
public function createApplication()
{
// set the unitTesting flag to true
$unitTesting = true;
// set the environment variable to 'testing'
$testEnvironment = 'testing';
return require __DIR__.'/../../bootstrap/start.php';
}
/**
* migrateDatabase() : load the sqlite database into memory
*/
private function migrateDatabase()
{
Artisan::call('migrate');
}
/**
* testHundredFilesMessage() : tests to see if custom message will
* return after 100 messages have been sent by the same user
*/
public function testHundredFilesMessage()
{
// TODO
$this->assertTrue(false);
}
/**
* testSixMonthMessage() : test the six months message
*/
public function testSixMonthMessage()
{
// TODO
$this->assertTrue(false);
}
/**
* testOneYearMessage() : test the one-year message
*/
public function testOneYearMessage()
{
// TODO
$this->assertTrue(false);
}
}
The first test seems to pass, but all subsequent tests throw errors. 第一个测试似乎通过,但所有后续测试都会抛出错误。 I am guessing that somehow the createApplication() method gets called several times which might explain why the Command
class DeleteExpiredSends
gets redefined; 我猜不知怎样多次调用createApplication()方法,这可能解释为什么Command
类DeleteExpiredSends
被重新定义; the class shows a define
statement in its constructor: 该类在其构造函数中显示一个define
语句:
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
define("SHARE_SEND_EXPIRATION", 14);
}
If anyone could tell me how to avoid redefinition for this unit test, so as to avoid modifying the internals of the Command
class, it would be most helpful. 如果有人能告诉我如何避免重新定义此单元测试,以避免修改Command
类的内部,那将是最有帮助的。 It only seems to be an issue where this unit test is concerned. 这个单元测试似乎只是一个问题。
For each test method add two annotations for phpunit, like this: 对于每个测试方法,为phpunit添加两个注释,如下所示:
/* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testPageShow()
{
I think for temporary solution while you are still not sure on where to put those global constants you have, make use of defined
instead. 我认为对于临时解决方案,虽然你仍然不确定在哪里放置那些全局常量,但是请使用defined
。
defined('SAMPLE_GLOBAL_CONSTANT')
or define('SAMPLE_GLOBAL_CONSTANT', 'sample value of the constant')
And by the way, in case you also run on redefinition exception for a global function you can also use of function_exists
method. 顺便说一句,如果你还运行全局函数的重定义异常,你也可以使用function_exists
方法。
But be sure to make use of Class instead to hold that global functions so you can easily test your application. 但是请确保使用Class来保存全局函数,以便您可以轻松地测试应用程序。 Like put it on something like Helper
or much more specific like StringHelper
. 就像把它放在像Helper
这样的东西上,或者像StringHelper
那样更具体。
使用SenseException的解决方案来删除所有的define
语句(事实证明在整个应用程序中只使用了两个),而使用类常量确实解决了这个问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.