2014-12-09 4 views
0

컨트롤러 메소드의 추가 동작을 테스트하고 싶습니다. 저장 작업 결과를 확인하고 싶습니다. 그래서 기본적으로 작업에 게시물을 보내고 요청이 끝난 후 찾기를 사용하여 테스트 결과를 확인하려고합니다. $ this-> testAction()이 올바른 방법이 아닌 것 같습니다 (아래 코드의 주석 참조). 어떻게해야합니까?CakePHP 컨트롤러 유닛 테스트

Public function add() { 
    ..... 
    if ($this->request->is('post') && isset($this->request->data['InvoiceEntry'])) { 
    .... 
    $this->request->data = $this->__someMethod($this->request->data); 
    if ($this->Invoice->saveAssociated($this->request->data)) { 
     .... 
     $this->redirect(array('action' => 'index')); 
    } 
    ..... 
} 

테스트 코드 :

public function testAdd() { 
    $data = array('Invoice' => array(...), 'InvoiceEntry' => array(....)); 

    // Method 1 
    $this->testAction('/invoices/add/', array(
     'method' => 'post', 
     'data' => $data, 
    )); 
    // Unable to do find after testAction because testAction basically is the test? 


    // Method 2: 
    $this->controller = $this->generate('Invoices'); 
    $_SERVER['REQUEST_METHOD'] = 'POST'; 
    $this->controller->requestAction('/invoices/add',array(
     'data' => $data 
    )); 
    // not working because requestAction() follows the redirect in the add method 
} 

답변

1

먼저 Model 클래스를 테스트 setUp() 메서드로 초기화해야합니다.

public function setUp() { 
    parent::setUp(); 
    $this->Invoice = ClassRegistry::init('Invoice'); 
} 

그런 다음 그 모델을 사용할 수 있습니다. 당신이 할 그래서 후 :

$this->testAction('/invoices/add/', array(
    'method' => 'post', 
    'data' => $data, 
)); 

가 수행하여, 예를 들어, 추가 된 경우는 확인 할 수 있어야한다 :처럼,

/* 
* Check if the last insert id is 13 
* (NOTE: This actual number depends on how your fixture looks.) 
*/ 
$this->assertEquals(13, $this->Invoice->getLastInsertID()); 

또는 일부 콘텐츠를 확인 :

// Find the latest invoice 
$invoice = $this->Invoice->find('first', array(
    'order' => array('id' => 'desc') 
)); 

/* 
* Verify the data matches your $data array 
* e.g. if the customer_id of this invoice is 1 
* (this depends on what is actually in $data) 
*/ 
$this->assertEquals(1, $invoice['Invoice']['customer_id']); 

마지막으로 tearDown() 메서드에서 Model 인스턴스를 소멸시키는 것을 잊지 마십시오.

public function tearDown() { 
    unset($this->Invoice); 
    parent::tearDown(); 
} 
+0

나는 TestCase :: setUp()에서 모델을 초기화해야한다는 사실에 동의하지 않는다. 이를 수행하는 것이 유일한 이유는 테스트 기능의 80 %에서 모델을 사용할 것이라는 것입니다. 그렇지 않으면 당신은 단지 거의 사용하지 않을 객체를 생성 할 것입니다. 나쁜 습관이 아닌 나쁜 습관입니다. – chadrien

1

당신은 testAction 후 아무것도 할 수 있어야한다

컨트롤러 코드는 같은입니다. 테스트 그 자체가 아니라 액션에서 코드를 실행합니다. testAction 뒤에 Model::find()을 입력하면 어떻게 되나요? 또는 debug('foo');exit;? 이것은 실행되어야합니다.

그런데 컨트롤러에서 리디렉션 앞에 return을 사용해야합니다. CakePHP는 터미널이 브라우저가 아니기 때문에 추천합니다. (webroot/test.php이 아닌 명령 줄을 사용하여 테스트한다고 가정하고 브라우저를 통한 테스트가 쿠키/세션으로 인해 일관성없는 테스트로 이어질 수 있으므로 터미널을 중지하고 사용하는 경우)) 리디렉션을 따르지 않으므로 Controller::redirect() 다음에 오는 코드가 실행되어 원하지 않습니다.

관련 문제