Testing redirections CakePHP 2.0

三世轮回 提交于 2019-12-23 13:27:06

问题


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

回答1:


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




回答2:


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



回答3:


The echo never be printed, your function "delete" always calls a redirect before ends.




回答4:


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, Isn't that totally wrong? You are deleting a comment and passing the comment's id to the post's view controller ? So, you're viewing the post or the comment by doing so?? Any other suggestion ?



来源:https://stackoverflow.com/questions/10179650/testing-redirections-cakephp-2-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!