CakePHP 控制器的实际测试?

2024-06-26

我正在使用 SimpleTest 1.0.1 用 CakePHP(刚刚发布的 1.2.4)编写一个新应用程序。我已经阅读了相关章节Cookbook http://book.cakephp.org/view/366/Testing-controllers, 搜索到Bakery http://bakery.cakephp.org/,并阅读 Mark Story 关于控制器测试的帖子(hard way http://mark-story.com/posts/view/testing-cakephp-controllers-the-hard-way and 与模拟 http://mark-story.com/posts/view/testing-cakephp-controllers-mock-objects-edition).

不幸的是,这些都没有讨论非平凡控制器的实际测试。许多应用程序将网站的某些区域置于登录后面,但我不知道如何测试以下简单场景:

  • 来宾访问受保护的页面重定向?
  • 有效的凭据设置预期的会话变量?
  • 无效的凭据重新显示登录页面并带有错误消息?

下面的控制器和测试并不像我想象的那样工作。两个断言都失败了,我还收到一个 PHP 错误:

失败的 [NULL] 在 [.../app/tests/cases/controllers/users_controller.test.php 第 79 行] 不应为空 .../app/tests/cases/controllers/users_controller.test.php -> UsersControllerTest -> testLogin

失败的 等期望失败,因为 [NULL] 与 [.../app/tests/cases/controllers/users_controller.test.php 第 80 行] 处的 [Integer: 1] 不匹配 .../app/tests/cases/controllers/users_controller.test.php -> UsersControllerTest -> testLogin

错误 意外的 PHP 错误 [未定义索引:操作] 严重性 [E_NOTICE] 在 [.../cake/libs/controller/components/auth.php 第 266 行] .../app/tests/cases/controllers/users_controller.test.php -> UsersControllerTest -> testLogin

这是控制器(烘焙加上 Mark Story 的“hard way”测试方法):

class UsersController extends AppController
{
  var $name = 'Users';
  var $helpers = array('Html', 'Form');
  var $components = array('Auth');

  function login()
  {
  }

  function logout()
  {
    $this->redirect($this->Auth->logout());
  }

  function index()
  {
    $this->set('users', $this->paginate());
  }

  function view($id = null)
  {
    if (!$id)
    {
      $this->Session->setFlash(__('Invalid User.', true));
      $this->redirect(array('action'=>'index'));
    }
    $this->set('user', $this->User->read(null, $id));
  }

  function add()
  {
    if (!empty($this->data))
    {
      $this->User->create();
      if ($this->User->save($this->data))
      {
        $this->Session->setFlash(__('The User has been saved', true));
        $this->redirect(array('action'=>'index'));
      }
      else
      {
        $this->Session->setFlash(__('The User could not be saved. Please, try again.', true));
      }
    }
  }

  function edit($id = null)
  {
    if (!$id && empty($this->data))
    {
      $this->Session->setFlash(__('Invalid User', true));
      $this->redirect(array('action'=>'index'));
    }
    if (!empty($this->data))
    {
      if ($this->User->save($this->data))
      {
        $this->Session->setFlash(__('The User has been saved', true));
        $this->redirect(array('action'=>'index'));
      }
      else
      {
            $this->Session->setFlash(__('The User could not be saved. Please, try again.', true));
      }
    }
    if (empty($this->data))
    {
      $this->data = $this->User->read(null, $id);
    }
  }

  function delete($id = null)
  {
    if (!$id)
    {
      $this->Session->setFlash(__('Invalid id for User', true));
      $this->redirect(array('action'=>'index'));
    }
    if ($this->User->del($id))
    {
      $this->Session->setFlash(__('User deleted', true));
      $this->redirect(array('action'=>'index'));
    }
  }
}

这是测试:

/* SVN FILE: $Id$ */
/* UsersController Test cases generated on: 2009-08-05 17:08:03 : 1249507923*/
App::import('Controller', 'Users');

class TestUsers extends UsersController
{
  var $autoRender = false;
  var $redirectUrl;
  var $redirectStatus;
  var $renderedAction;
  var $renderedLayout;
  var $renderedFile;
  var $stopped;

  function redirect($url, $status = null, $exit = true)
  {
    $this->redirectUrl = $url;
    $this->redirectStatus = $status;
  }

  function render($action = null, $layout = null, $file = null)
  {
    $this->renderedAction = $action;
    $this->renderedLayout = (is_null($layout) ? $this->layout : $layout);
    $this->renderedFile = $file;
  }

  function _stop($status = 0)
  {
    $this->stopped = $status;
  }
}

class UsersControllerTest extends CakeTestCase
{
  var $fixtures = array('user');
  var $Users = null;

  function startTest()
  {
    $this->Users = new TestUsers();
    $this->Users->constructClasses();
    $this->Users->Component->initialize($this->Users);
  }

  function prepareForAction()
  {
    $this->Users->beforeFilter();
    $this->Users->Component->startup($this->Users);
  }

  function endTest()
  {
    $this->Users->Session->destroy();
    unset($this->Users);
    ClassRegistry::flush();
  }

  //-----------------------------------------------------------------------

  function testUsersControllerInstance()
  {
    $this->assertTrue(is_a($this->Users, 'UsersController'));
  }

  function testLogin()
  {
    $this->Users->data = array(
      'User' => array(
        'username' => 'admin',
        'password' => 'admin'
      )
    );

    $this->prepareForAction();
    $this->Users->login();

    $this->assertNotNull($this->Users->redirectUrl);
    $this->assertEqual($this->Users->Session->read('Auth.User.id'), 1);
  }
}

您进行的测试并不是真正测试您的 UsersContoller,而是真正测试 AuthComponent。如果你想这样做,你需要确保你的 TestUsersController 设置与你的应用程序中的设置相同。对于 testLogin,您需要设置控制器的操作和 url:

function testLogin()
{
 $this->Users->data = array(
              'User' => array(
                    'username' => 'admin',
                    'password' => 'admin'
                  )
            );

 $this->Users->params['url']['url'] = '/users/login';
 $this->Users->params['action'] = 'login';
 $this->prepareForAction();
 $this->Users->login();

 $this->assertNotNull($this->Users->redirectUrl);
 $this->assertEqual($this->Users->Session->read('Auth.User.id'), 1);
}

或者,我建议再看一下马克的模拟对象帖子 http://mark-story.com/posts/view/testing-cakephp-controllers-mock-objects-edition并使用这些方法为控制器代码编写测试并模拟身份验证组件。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CakePHP 控制器的实际测试? 的相关文章

随机推荐