Тестирование перенаправлений CakePHP 2.0

Я смотрел на некоторые примеры в кулинарной книге, но я не понимаю: http://book.cakephp.org/2.0/en/development/testing.html

Как я могу проверить перенаправление в действии удаления как это?

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

4 ответа

Решение

Тестирование вашего действия удаления должно быть примерно таким же, как тестирование любого другого действия. Ваш тестовый пример может выглядеть примерно так.

// 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 метод на ControllerTestCase,

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 для использования во время тестирования. Это также издевается над send() метод для EmailComponent и всего SessionComponent.

Для получения дополнительной информации о насмешках: http://www.phpunit.de/manual/3.0/en/mock-objects.html

Для получения дополнительной информации о generate(): http://book.cakephp.org/2.0/en/development/testing.html

Возможно, у вас есть ошибка, потому что $idPost не определено

Я бы написал что-то вроде этого:

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

Эхо никогда не будет напечатано, ваша функция "удалить" всегда вызывает перенаправление до конца.

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, разве это не совсем неправильно? Вы удаляете комментарий и передаете идентификатор комментария в контроллер представления сообщения? Итак, вы просматриваете сообщение или комментарий, делая это?? Любое другое предложение?

Другие вопросы по тегам