Unit testing 测试重定向CakePHP 2.0
我一直在看烹饪书上的一些例子,但我不明白: 如何在这样的删除操作中测试重定向Unit testing 测试重定向CakePHP 2.0,unit-testing,cakephp,testing,redirect,cakephp-2.0,Unit Testing,Cakephp,Testing,Redirect,Cakephp 2.0,我一直在看烹饪书上的一些例子,但我不明白: 如何在这样的删除操作中测试重定向 public function delete($id = null){ $this->Comment->id = $id; if (!$this->Comment->exists()) { throw new NotFoundException(__('Invalid comment')); }
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);
}
永远不会打印回显,函数“delete”总是在结束前调用重定向。测试删除操作应该与测试任何其他操作相对相同。您的测试用例可能看起来像这样
// 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());
}
}
当然,这只是检查明显的问题。您还可以检查会话并编写预期出现异常的测试。如果它仍然没有到达测试用例的结尾或继续,则会发生其他事情
您可以使用ControllerTestCase
上的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()
方法
有关模拟的详细信息:
有关
generate()
的详细信息:可能是由于$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));
}
}
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');
}
}
普莱尼克斯,
这不是完全错了吗?
您正在删除注释并将注释的id传递给帖子的视图控制器?那么,你这样做是在看帖子还是评论??还有其他建议吗?我想知道它是否抛出了空视图错误。在这种情况下,您可以尝试在控制器上模拟
render
函数,因为没有删除视图。模拟它是什么意思?是的,没有,重定向工作正常,视图操作不是空的。模拟是一个测试过程,你可以让某些方法返回你想要的。例如,CakeRequest::send()
被模拟,并被告知什么也不做,因此它不发送头。您甚至可以告诉被模拟的方法期望什么或如何响应(请参阅:)。要使用蛋糕轻松进行模拟,请查看:ControllerTestCase::testAction()
会自动为您执行一些操作。我一直在尝试,但没有成功。这样做不是更简单吗?这可能会显著改变代码的行为。我会在一分钟内给出一个正确的答案。在这个电话之后:$this->testAction('/posts/delete/1');没有执行任何操作。所以我甚至不能做$results=$this->headers['Location'];重定向停止了它。那么听起来好像发生了什么事情。尝试发布完整的测试用例,在delete()
操作中分散一些调试语句,用另一个使用重定向的操作检查它,等等。