简体   繁体   English

Laravel单元测试:运行多个测试方法时重新定义错误

[英]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()方法,这可能解释为什么CommandDeleteExpiredSends被重新定义; 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()
{
  • runInSeparateProcess : run each test in a separate process runInSeparateProcess:在单独的进程中运行每个测试
  • preserveGlobalState disabled : disable global state from previous test preserveGlobalState disabled:禁用先前测试的全局状态

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.

相关问题 使用laravel运行单元测试时,如何测试App :: error()实现? - When running unit tests with laravel, how do you test your App::error() implementations? 在 Laravel 8 中运行多个 PHPUnit 测试时出错 - Error when running multiple PHPUnit Tests in Laravel 8 使用多种方法时Laravel单元测试控制器错误 - Laravel Unit testing controllers error when using multiple methods Laravel单元测试未在Windows上运行 - Laravel unit tests not running on windows 在 Laravel 8 的单元测试中调用未定义的方法 Tests\\Unit\\TopPageTest::get() - Call to undefined method Tests\Unit\TopPageTest::get() in Unit test in Laravel 8 如何测试验证错误在 laravel 单元测试中抛出确切的错误和消息 - How to test validation errors throw exact error and message in laravel unit tests PHP单元测试:是否可以测试致命错误? - PHP Unit Tests: Is it possible to test for a Fatal Error? laravel在模拟邮件时进行测试,但是在运行端到端测试时会传递邮件 - laravel tests when mocking mail, however mail get delivered when running an end-to-end test Laravel 5.7中PHP单元测试之间的测试依赖关系 - Test Dependencies between PHP unit tests in Laravel 5.7 Laravel 单元测试 - 根据测试方法更改配置值 - Laravel unit tests - changing a config value depending on test method
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM