Testing controller actions and their views

In this recipe, we will learn how to test controller actions and ensure that their views produce the result we expect.

Getting ready

To go through this recipe we need a basic application skeleton to work with, and have the SimpleTest library installed. Go through the entire recipe Setting up the test framework.

We also need test data. Go through the creation of fixtures described in the recipe Creating fixtures and testing model methods.

How to do it...

Create a file named articles_controller.test.php and place it in your app/tests/cases/controllers folder, with the following contents:

<?php
class ArticlesControllerTestCase extends CakeTestCase {
public $fixtures = array('app.article', 'app.user', 'app.vote'),
public function testView() {
$result = $this->testAction('/articles/view/1', array('return'=>'vars'));
$expected = array(
'Article' => array(
'id' => 1,
'title' => 'Article 1',
'body' => 'Body for Article 1'
),
0 => array(
'vote' => 4.3333
)
);
$this->assertTrue(!empty($result['article']));
$this->assertEqual($result['article'], $expected);
$result = $this->testAction('/articles/view/1', array('return'=>'view'));
$this->assertTags($result, array(
array('h1' => array()),
'Article 1',
'/h1',
'Vote:',
array('span' => array('id'=>'vote')),
'4.3',
'/span',
array('p' => array()),
'Body for Article 1',
'/p'
));
}
?>

If you now browse to http://localhost/test.php, click on the Test Cases option under the App section in the left menu, and then click on the controllers / ArticlesController test case, you should see our unit test succeeding, as shown in the next screenshot:

How to do it...

How it works...

We start by creating the test case in a class named ArticlesControllerTestCase, and save it in its proper location (app/tests/cases/controllers), using the right filename (articles_controller.test.php). In this class, we specify which fixtures we need to load, which, just as it was shown in the recipe Creating fixtures and testing model methods, consists of fixtures for all the loaded models.

Our test case includes a single unit test method: testView(), which intends to unit test the ArticlesController::view() action. In this unit test we use the testAction() method that is available to all test cases. This method takes two arguments:

  • url: This is either a string or an array containing the URL to the controller action we intend to test. If it is an array, it should be in the same format as the format used by CakePHP once a string-based URL has been parsed.
  • parameters: This is a set of optional parameters, which can be any of the following:
    • connection: If fixturize is set to true, it defines the connection from where to import data.
    • data: It is the data to post to the controller.
    • fixturize: If this is set to true, then all data from the connection defined in the connection setting will be imported into fixtures for all the used models. Defaults to false.
  • method: This is the method to use when posting the data specified in the data setting. Can either be get or post. Defaults to post.
  • return: This specifies the type of result that should be returned as a result of a testAction() call. If it is set to result, which is the default, it will return whatever the controller action returns. If it is set to vars, it will return the view variables assigned from the action. If it is view, it will return the rendered view without the layout. Finally, if it is set to contents, it will return the rendered view within its layout.
  • testView(): The testView() method calls the view() action with a proper ID, and tells the testAction() method to return the view variables created in the controller action. We make sure that this variable is set to the proper article information. We then finalize with a call to testAction(), using the same URL, but specifying that we want to obtain the rendered view.

To assert that the view has the proper content, we use the assertTags() method, which offers a flexible way to check HTML tags. This method takes an array of elements, each element being either a string that represents a static string or a closing tag if the string starts with a forward slash, or an array, where the key is an HTML tag name, and the value is itself an array of attributes (keys being the attribute names, and values being their respective values).

There's more...

We have seen how, by using testAction(), we can easily test our controller actions and make assertions on either the action's return value, the view variables, or the view content. However, we have not covered how to test actions that might redirect the user away from the current action, or how to test for session operations. The next recipe shows how to add more complex tests to the unit tests we have just built.

See also

  • Using mocks to test controllers
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.174.204