2014-12-09 5 views
0

Я хочу проверить действие добавления метода контроллера. Я хочу проверить результат действия сохранения. Поэтому в основном я хочу отправить сообщение в действие и проверить результат в своем тесте, используя find после завершения запроса. $ 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

Прежде всего, вы должны инициализировать класс модели в методе 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():

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

Я не согласен с тем, что вы должны инициализировать модель в TestCase :: setUp(). Единственная причина, по которой это нормально, заключается в том, что вы будете использовать модель на 80% тестовых функций. В противном случае вы просто создадите объект, который вы в основном просто не используете. Это не плохая практика, а какая-то дурная привычка. – chadrien

1

Вы должны быть в состоянии сделать что-либо после testAction. Это не сам тест, он просто запускает код в действии. Что произойдет, если вы сделаете Model::find() после вашего testAction? Или даже debug('foo');exit;? Это должно быть выполнено.

Кстати, в вашем контроллере вы должны использовать return перед перенаправлением. Это рекомендуется CakePHP, потому что терминал не является браузером (я предполагаю, что вы проверите с командной строкой, а не с webroot/test.php, и если вы остановитесь и используете терминал, поскольку тестирование через ваш браузер может привести к некогерентным испытаниям из-за куки-файлов/сеансов) и не будет следовать перенаправлению, поэтому будет выполняться код, который может быть после Controller::redirect(), и вы этого не хотите :)

Смежные вопросы