简体   繁体   English

Zend框架,PHPUnit和事务

[英]Zend Framework, PHPUnit and transactions

i want to use PHP Unit inside a Zend Framework application. 我想在Zend Framework应用程序中使用PHP Unit。 I need to make several database writing operations inside the tests. 我需要在测试中进行几次数据库写操作。 I want to start an MySQL transaction in the setUpBeforeClass() method. 我想在setUpBeforeClass()方法中启动MySQL事务。 That is possible, but if I try to rollback the transaction in the tearDownAfterClass() method he throws an exception with the message 'There is no active transaction'. 这是可能的,但是如果我尝试在tearDownAfterClass()方法中回滚事务,他将引发异常,并显示消息“没有活动的事务”。 And the test methods does the writing operations in the database. 测试方法在数据库中执行写操作。 But if i start the transaction in the test method itselfs. 但是,如果我以测试方法本身开始交易。 It works like I want. 它像我想要的那样工作。 I don't understand why it reacts like this. 我不明白为什么它会这样反应。 Knows anyone an explanation? 知道有人解释吗?

<?php

class ConferenceControllerTest
extends PHPUnit_Framework_TestCase
{

    /**
     * A database connection.
     * @var Zend_Db_Adapter_Pdo_Mysql
     */
    protected static $hostDb = null;

    public static function setUpBeforeClass()
    {
        static::$hostDb = Zend_Registry::get('db_host');
        static::$hostDb->beginTransaction();
        // The transaction for the Adapter is activated. But not inside the tests anymore.
    }


    public function testTest1()
    {
        // At this position teh transaction is not setted anymor? Why?
        static::$hostDb->beginTransaction();

        $sql = 'INSERT INTO test(test) VALUES(5);';
        static::$hostDb->exec($sql);
    }

    public static function tearDownAfterClass()
    {
        try
        {
            static::$hostDb->rollBack();
        }
        catch(Exception $exception)
        {
            $message = $exception->getMessage();
            Zend_Debug::dump($message);
        }
    }

}

I think you may be running into phpUnit's feature to backup statics and other globals between each unit test, see the "globals" section of the Fixtures chapter of the manual 我认为您可能正在使用phpUnit的功能来在每个单元测试之间备份静态数据和其他全局变量,请参见手册“夹具”一章的“全局变量”部分

The quick-hack fix would be to add this line, in the comments just above your class: * @backupStaticAttributes disabled 快速修复方法是在类上方的注释中添加以下行:* @backupStaticAttributes disabled

That still leaves you with the xUnit Patterns book would call a nasty smell. 仍然使您留在xUnit Patterns书中,这会让人讨厌。 I'm assuming you have a few testXXX functions that you expect to run in a certain order, each depending on the result of the previous one? 我假设您希望以某种顺序运行一些testXXX函数,每个函数取决于上一个函数的结果? That requires using @depends on each function, and it is easy to get wrong. 这需要在每个函数上使用@depends,很容易出错。

The alternative approach is a single long unit test function, and put the DB code in setUp() and tearDown(): 另一种方法是单个长单元测试功能,并将数据库代码放入setUp()和tearDown()中:

public function setUp()
{
    $this->db = Zend_Registry::get('db_host');
    $this->db->beginTransaction();
}

public function tearDown()
{
    try
    {
        $this->db->rollBack();
    }
    catch(Exception $exception)
    {
        $message = $exception->getMessage();
        Zend_Debug::dump($message);
    }


public function testTestVariousDBActions()
{
    $sql = 'INSERT INTO test(test) VALUES(5);';
    $this->db->exec($sql);

    //another DB action
    $this->assertEquals(...)

    //another DB action
    $this->assertEquals(...)

    //...
}

The advantage of this is that if any assert fails none of the subsequent ones will be attempted. 这样做的好处是,如果任何断言失败,则不会尝试任何后续断言。 But tearDown() will always be called so the database is restored. 但是,始终会调用tearDown()以便还原数据库。

The disadvantage could be you get a Very Long Function. 缺点可能是您获得了非常长的函数。 Use refactoring to deal with this (eg if you really want each action and its test in its own function, refactor so it looks like that and have testTestVariousDBActions() call each of them in turn). 使用重构来解决这个问题(例如,如果您真的希望每个动作及其测试都在其自己的函数中进行,则进行重构,使其看起来像这样,并testTestVariousDBActions()调用testTestVariousDBActions() )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM