I have been looking at some examples at the cookbook but i dont get it: http://book.cakephp.org/2.0/en/development/testing.html#a-more-complex-example
How can i test a redirection in a delete action like this one?
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));
}
}
The test stops after the redirect call, so it doesn't even print this echo:
public function testDelete(){
$result = $this->testAction("/comments/delete/1");
echo "this is not printed";
print_r($this->headers);
}
Testing your delete action should be relatively the same as testing any other action. Your test case might look something like this.
// 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());
}
}
Of course, this just checks the obvious. You can also check the session and write a test that expects the exception. If it's still not reaching the end of the test case or continuing on, something else is going on.
You can generate easy mocks by using the generate
method on 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');
}
The above would first generate a mock of the PostsController to use during testing. It also mocks the send()
method on the EmailComponent, and the entire SessionComponent.
For more information on mocking: http://www.phpunit.de/manual/3.0/en/mock-objects.html
For more information on generate()
: http://book.cakephp.org/2.0/en/development/testing.html#using-mocks-with-testaction
Possible you have an error because $idPost
is undefined.
I would write something like this:
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));
}
}
And test it's like this:
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');
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With