一个空的 tearDown 方法使 phpunit 测试通过

Posted

技术标签:

【中文标题】一个空的 tearDown 方法使 phpunit 测试通过【英文标题】:an empty tearDown method makes the phpunit test passess 【发布时间】:2018-07-04 20:39:54 【问题描述】:

**我在 Laravel 5.3 中有以下 Test 类,你可以看到 tearDown() 方法是空的,我在内存中使用 sqlite 进行测试。 现在测试正在通过,但是当我删除空的tearDown() 方法时,它会抛出一个foreign key contraint failed exception, 我正在使用 sqlite 进行测试,phpunit.xml 配置如下。 我已经尝试将测试数据库更改为 mysql,那时一切正常(即使没有tearDown())。知道为什么没有 tearDown() 方法会导致错误吗?

use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Database\Eloquent\Model;
use App\Country;

class PhoneTest extends TestCase

    use DatabaseMigrations;

    public function setUp()
    
        parent::setUp();

        Schema::disableForeignKeyConstraints();

        $this->seed(LocationsSeeder::class);

        Schema::enableForeignKeyConstraints();
    

    public function test_we_can_make_number_international()
    
        $phoneService  = resolve('Phone');
        $international = $phoneService->makeInternational('0507639889', Country::find(1));

        return $this->assertEquals($international, '+971507639889');
    


    protected function tearDown()
    
        //
    

环境: Laravel 5.3, 测试数据库:sqlite - 内存 phpunit 4.8.36 php - 7 PHPUnit 配置

 <php>
        <env name="APP_ENV" value="testing"/>
        <env name="DB_CONNECTION" value="sqlite"/>
        <env name="DB_DATABASE" value=":memory:"/>
        <env name="CACHE_DRIVER" value="array"/>
        <env name="SESSION_DRIVER" value="array"/>
        <env name="QUEUE_DRIVER" value="sync"/>
    </php>

编辑:我在新数据库上的迁移工作正常,甚至向上和回滚

【问题讨论】:

【参考方案1】:

由于您使用的是 DatabaseMigrations trait,Laravel 会尝试执行 migrate:rollback 命令:

 $this->beforeApplicationDestroyed(function () 
     $this->artisan('migrate:rollback');
 );

而且由于您的迁移很混乱(这就是您关闭 FK 约束的原因),所以它会失败。

当您放置tearDown() 方法时,您将覆盖父Illuminate\Foundation\Testing\TestCase 类中的tearDown() 方法,因此永远不会执行beforeApplicationDestroyed 回调。

处理这个问题的最好方法是在每次迁移中修复down() 方法,这样每个表都可以在migrate:rollback 命令执行时被删除。但您也可以从 tearDown() 方法运行 migrate:reset。或者使用disableForeignKeyConstraints() 来禁用FK 约束,就像在setUp() 方法中所做的那样。

【讨论】:

但有一件事,为什么当我将测试数据库更改为 mysql 时这会起作用? 感谢@Alexy Mezenin 的帮助

以上是关于一个空的 tearDown 方法使 phpunit 测试通过的主要内容,如果未能解决你的问题,请参考以下文章

PHPUnit 运行程序

如果重写setUp和tearDown,则不会调用PHP,phpunit和dbunit - getConnection和getDataSet

PHPUnit测试和Doctrine,连接太多

按特定顺序运行 PHPUnit 测试

Laravel 5 使用 phpUnit 进行测试而不重置我的数据库

使netbeans使用phpunit的虚拟盒客户端安装