2012-04-16 4 views
3

나는 요리 책에서 몇 가지 예를 찾고있다하지만 난 그것을 얻을 해달라고 : http://book.cakephp.org/2.0/en/development/testing.html#a-more-complex-example테스트 리디렉션 CakePHP는 2.0

이 어떻게 이와 같은 삭제 작업에 리디렉션을 테스트 할 수 있습니다 ?

public function delete($id = null){   
     $this->Comment->id = $id; 
     if (!$this->Comment->exists()) { 
      throw new NotFoundException(__('Invalid comment')); 
     } 
     if ($this->Comment->delete()) {   
      $this->Session->setFlash(__('Comment deleted')); 
      return $this->redirect(array('controller' => 'posts', 'action' => 'view', $idPost)); 
     } 
     $this->Session->setFlash(__('Comment was not deleted')); 
     return $this->redirect(array('controller' => 'posts', 'action' => 'view', $idPost));   
    } 
} 

테스트는 리디렉션 호출 후에 중지, 그래서 심지어이 에코 인쇄되지 않습니다 에코 인쇄되지 않을

public function testDelete(){  
    $result = $this->testAction("/comments/delete/1"); 
    echo "this is not printed"; 
    print_r($this->headers);   
} 
+0

빈 뷰 오류가 발생하는지 궁금합니다. 이 경우 컨트롤러에서'render' 함수를 조롱 해 볼 수 있습니다. 어쨌든 삭제보기가 없기 때문입니다. – jeremyharris

+0

조롱하는 것은 무엇을 의미합니까? 그리고 네, 아니, 리디렉션이 잘 작동하고보기 작업이 비어 있지 않습니다. – Alvaro

+0

조롱은 특정 방법으로 원하는 것을 반환하도록 테스트하는 절차입니다. 예를 들어,'CakeRequest :: send()'는 조롱을 당했고 아무 것도하지 말라고 명령하고, 그래서 헤더를 보내지 않는다. 조롱 된 방법에 대해 무엇을 기대할 것인지 또는 어떻게 대응할 것인지를 알 수 있습니다 (http://www.phpunit.de/manual/3.0/en/mock-objects.html 참조). Cake를 쉽게 조롱하려면 http://book.cakephp.org/2.0/en/development/testing.html#using-mocks-with-testaction을 확인하십시오.'ControllerTestCase :: testAction()'은 이것을 자동으로 수행합니다. – jeremyharris

답변

6

삭제 작업 테스트는 다른 작업 테스트와 상대적으로 동일해야합니다. 테스트 케이스가 다음과 같이 보일 수 있습니다.

// notice it extends ControllerTestCase 
class PostsControllerTest extends ControllerTestCase { 

    function testDelete() { 
     $this->testAction('/posts/delete/1'); 
     $results = $this->headers['Location']; 
     // your OP code redirected them to a view, which I assume is wrong 
     // because the item would be deleted 
     $expected = '/posts/index'; 
     // check redirect 
     $this->assertEquals($results, $expected); 

     // check that it was deleted 
     $this->Posts->Post->id = 1; 
     $this->assertFalse($this->Posts->Post->exists()); 
    } 

} 

물론 이것은 명백한 것입니다. 또한 세션을 확인하고 예외를 예상하는 테스트를 작성할 수 있습니다. 그래도 테스트 케이스가 끝나지 않았거나 계속 진행 중이면 그 밖의 것이에 있습니다.

generate 메서드를 사용하여 의 쉬운 모의을 생성 할 수 있습니다.

function testDelete() { 
    $Posts = $this->generate('Posts', array(
    'components' => array(
     'Email' => array('send'), 
     'Session' 
    ) 
)); 
    // set ControllerTestCase to use this mock 
    $this->controller = $Posts; 

    $this->testAction('/posts/some_action_that_sends_email'); 
} 

위의 코드는 먼저 테스트 중에 사용할 PostsController 모의를 생성합니다. 또한 EmailComponent와 전체 SessionComponent에서 send() 메서드를 조롱합니다. 조롱에 대한 자세한 내용은

: http://www.phpunit.de/manual/3.0/en/mock-objects.html 자세한 내용은

generate()에 : $idPost이 정의되어 있기 때문에 http://book.cakephp.org/2.0/en/development/testing.html#using-mocks-with-testaction

+0

이 호출 후 $ this-> testAction ('/ posts/delete/1'); 아무것도 실행되지 않습니다. 그래서 나는 $ results = $ this-> headers [ 'Location']도 할 수 없다; 리디렉션이 중지합니다. – Alvaro

+0

다른 일이 일어나고있는 것 같습니다. 전체 테스트 케이스를 게시하고, 일부 디버그 문을'delete()'액션에 분산시키고, 리다이렉트를 사용하는 다른 액션으로 체크하십시오. – jeremyharris

0

, 함수는 "삭제"항상 종료되기 전에 리디렉션 호출합니다.

1

가능한 오류가 있습니다.

I는 다음과 같이 작성합니다

public function delete($id = null){   
     $this->Comment->id = $id; 
     if (!$this->Comment->exists()) { 
      throw new NotFoundException(__('Invalid comment')); 
     } 
     if ($this->Comment->delete()) {   
      $this->Session->setFlash(__('Comment deleted')); 
     } else { 
      $this->Session->setFlash(__('Comment was not deleted')); 
     } 
     $this->redirect(array('controller' => 'posts', 'action' => 'view', $id));   
    } 
} 

를 그리고이처럼 테스트 :

public function testDeleteWithSuccess() { 
     $Controller = $this->generate('Comments', array(
      'components' => array(
       'Session' 
      ), 
      'models' => array(
       'Comment' => array('exists') 
      ) 
     )); 

     $Controller->Comment->expects($this->once()) 
      ->method('exists') 
      ->will($this->returnValue(true)); 

     $Controller->Session->expects($this->once()) 
      ->method('setFlash') 
      ->with('Comment deleted'); 

     $this->testAction("/comments/delete/ID"); 

     $this->assertEquals($this->headers['Location'], 'http://'. $_SERVER['HTTP_HOST'] . '/posts/view/ID'); 
    } 
0
public function delete($id = null){   
    $this->Comment->id = $id; 
    if (!$this->Comment->exists()) { 
     throw new NotFoundException(__('Invalid comment')); 
    } 
    if ($this->Comment->delete()) {   
     $this->Session->setFlash(__('Comment deleted')); 
    } else { 
     $this->Session->setFlash(__('Comment was not deleted')); 
    } 
    $this->redirect(array('controller' => 'posts', 'action' => 'view', $id));   
} 

}

Plenix이 가 완전히 잘못 아닌가? 댓글을 삭제하고 댓글의 ID를 소식의보기 컨트롤러에 전달 하시겠습니까? 그래서, 그렇게함으로써 게시물이나 코멘트를보고 있습니까? 다른 제안?

관련 문제