2012-08-23 2 views
0

Zend Framework 응용 프로그램에서 PHP Unit을 사용하고 싶습니다. 테스트 내에서 여러 데이터베이스 쓰기 작업을해야합니다. setUpBeforeClass() 메소드에서 MySQL 트랜잭션을 시작하려고합니다. 그것은 가능하지만 tearDownAfterClass() 메소드에서 트랜잭션을 롤백하려고하면 '활성 트랜잭션이 없습니다.'라는 메시지와 함께 예외가 발생합니다. 그리고 테스트 메소드는 데이터베이스에서 쓰기 작업을 수행합니다. 하지만 테스트 메서드 자체에서 트랜잭션을 시작합니다. 그것은 내가 원하는 것처럼 작동합니다. 왜 이렇게 반응하는지 이해할 수 없습니다. 누구 한테 설명하는 줄 알아?Zend Framework, PHPUnit 및 거래

<?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); 
     } 
    } 

} 

답변

0

나는, 바로 위의 의견에, 빠른 해킹 수정이 줄을 추가하는 것입니다 the "globals" section of the Fixtures chapter of the manual

참조 백업의 정적 및 각 단위 테스트 사이에 다른 전역에 phpunit을의 기능으로 실행 할 수있다 생각 귀하의 클래스 : * @backupStaticAttributes 비활성화

여전히 xUnit 패턴 책을 남기게되면 불쾌한 냄새가 날 것입니다. 나는 당신이 몇 가지 testXXX 함수를 가지고 있다고 가정하고 있는데, 각각의 함수는 특정 순서로 실행될 것으로 예상된다. 각 기능에서 @depends를 사용해야하므로 잘못된 결과를 내기 쉽습니다.

다른 접근법은 하나의 긴 유닛의 테스트 기능이고, DB 설정 코드() 해체()를 입력 :

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(...) 

    //... 
} 

이 방법의 장점은 임의의 어설 후속 전혀 실패하지 않으면 사람은 시도 될 것이다. 그러나 tearDown()은 항상 호출되어 데이터베이스가 복원됩니다.

단점은 매우 긴 기능을 얻을 수 있다는 것입니다. 리팩토링을 사용하여이를 처리합니다 (예 : 각 액션과 해당 테스트를 자체 함수, 리펙터에서 실제로 원하는 것처럼 보이게하고 차례대로 각각 testTestVariousDBActions()을 호출하는 경우).