2013-05-28 3 views
0

면책 조항 : 예, FAQ를 읽고 Stackoverflow의 경계 내부에서 이러한 질문을 생각해보십시오. 아니, 이름을 올바르게 지정하는 방법을 모르겠습니다. :(단위 테스트 및 리팩토링하는 방법이 PHP 함수?

내 질문은 간단하다 : 어떻게 단위 시험 다음과 같은 방법 나는 검증 나는 반복하기 위해 무엇을해야하는지 리팩토링 : 나는 주위에 떠있는 DB와 YII 응용 프로그램 인스턴스를 필요로하지 않으 이 기능을 테스트합니다.이 매뉴얼은 전체 응용 프로그램을 테스트하여 유효성 검사 레거시 코드

public function getOrderCountGroupedByStatus() 
{ 
    $arr = $this->db->createCommand() 
     ->select('COUNT(status) AS count_status, status') 
     ->from('order_item') 
     ->group('status') 
     ->order('status') 
     ->queryAll(); 

    $orderItemsCountByStatus = array(); 
    foreach($arr as $os) 
     $orderItemsCountByStatus[(int)$os['status']] = $os['count_status']; 

    return $orderItemsCountByStatus; 
} 

입니다.

그것은 Yii framework에 따라 PHP 응용 프로그램에서의합니다.

$this->dbCDbConnection 개체입니다. $this->db->createCommand()CDbCommand 개체를 반환합니다.

CDbCommand.queryAll()은 각 반복마다 array('status' => (string), 'count_status' => (int)) 배열을 방출하는 반복 가능한 객체를 반환합니다.

이 방법에는 분명히 두 가지 책임이 있습니다. 첫 번째는 외부 데이터 원본에서 원시 데이터를 가져오고 두 번째는 최종 결과로 다시 정렬합니다. 어떻게 든 분리되어야한다는 것을 이해합니다.

  1. 데이터베이스에 대한 인터페이스는 체인 가능한 메소드로 오브젝트를 리턴하는 팩토리 메소드를 사용합니다. 이것은 조롱 할 악몽이다. 나는 CDbCommand와 그것을 만드는 CDbConnection 모두를위한 수동 가짜를 작성하기 시작했으나, 이미 너무 많은 코드를 작성하여 아마도 자신의 유닛 테스트가 필요할 것입니다. 데이터베이스에 요청을 모의하는 방법을 전혀 이해하지 못합니다.
  2. 이 코드는 단지 하나의 예일뿐입니다. 비슷한 방법이 많이 있지만 많은 사람들이 데이터베이스를 한 번만 호출하지 않고 여러 번 호출하기 때문에 "원시 데이터 가져 오기, 다시 포맷"은 아마 여기 패턴이 아니지만 확실하지는 않습니다. 내가 여기 테스트입니다하는 것은 관련 phpunit을 시험 방법의 이름으로 설명되어 있습니다 : 마지막으로

public function CanFindNumberOfOrdersGroupedByStatus() 
내가 여기에 붙어있는 이유

주된 이유는 내가 테스트 무엇을 기본적으로 이다 인 SUT 할 수 있는지 여부 지속 저장 장치에서 일부 통계를 성공적으로 가져 왔습니다. DB와의 모든 상호 작용은 여기 구현 세부 사항이지만, 내가 작업하고있는 레거시 코드베이스에서는 (CDbCommand/CDbConnection 콤보를 사용하여) 퍼시스턴스 스토리지에 연결하는 유일한 방법이며이 퍼시스턴스 스토리지는 MySQL 데이터베이스입니다.

CDbConnection을위한 완벽한 백엔드를 구현해야 할 필요가 있는지 궁금합니다. 이러한 방법은 실제 DB 대신 메모리 내 고정 장치로 작동하여 이러한 메서드를 제대로 테스트 할 수 있습니다.

예, 가능한 질문을 방지하기 위해 Yii 프레임 워크에 내장 된 ActiveRecords의 사용은 프로젝트 정치로 금지되어 있습니다.

+1

별도의 테스트 DB를 설정하고 알려진 결과를 테스트하십시오. –

+0

@IvoRenkema 이봐, 나는 여기서 단위 테스트에 대해 이야기하고있다. 모든 문제는 실제 DB를 사용하지 않는 것입니다 ** 그렇지 않으면 모든 사람들이 그러한 함수를 테스트하는 방법을 알고 있습니다. – hijarian

답변

-1

테스트를 위해 많은 코드를 작성할 필요는 없습니다. Yii는이 레거시 기능을 완벽하게 다루는 DB 테스트 및 DB 고정 기능을 포함한 우수한 테스트 프레임 워크를 보유하고 있습니다.당신의 독서를 들어

:

Testing in Yii은 (섹션 안에 설비에 또한 참조) 당신이 일을 끝낼 것입니다 무엇 일반적으로

은 다음과 같습니다 규정

  1. 테스트 설정 및 테스트 부트 스트랩 파일을 설정 (기본 예제 앱은 샘플 테스트 설정/부트 스트랩 설정을 포함합니다).
  2. 스키마를 사용하여 테스트 DB를 만들고 테스트 구성을 가리 키십시오.
  3. CDbTestCase까지 확장되는 클래스를 작성하십시오. 이것은 DB 픽스처를 이용한 테스트를 더 쉽게 해주는 Yii의 특별한 추가 기능을 가진 평범한 PHPUnit 테스트입니다. PHPUnit에 익숙하지 않은 분은 the docs을 참조하십시오.
  4. Yii 가이드에 따라 테스트 DB에 대한 몇 가지 비품을 작성하십시오. 이렇게하면 테스트 DB에 대한 테스트 데이터가 보장됩니다.
  5. Order 클래스의 기능을 "있는 그대로"호출하고 일반 단위 테스트와 마찬가지로 결과를 주장하는 테스트를 작성합니다. (당신의 단위 테스트 CDbTestCase 서브 클래스 내부 코드) :

    $ this-> assertEquals ( 배열 (1 => 2, 2 => 5), 주문하기 :: 모델() -> getOrderCountGroupedByStatus() );

+0

나는 한 주석 자에게 대답했고, 당신에게 대답했다 : 나는이 기능을 테스트하기 위해 전체 MySQL 인스턴스를 생성하고 Yii 애플리케이션을 인스턴스 할 필요도없고 싶지도 않다. ** unit ** 테스트가 필요합니다. 통합 테스트가 아닙니다. 고맙습니다. Yii와 DB 테스트를 설정하는 방법을 완벽하게 알고 있습니다. – hijarian