CakePHP kontrolörlerin gerçek dünya testi?

1 Cevap php

Ben SimpleTest 1.0.1 kullanarak, (1.2.4 sadece yayımlanan) CakePHP ile yeni bir uygulama yazıyorum. Ben Cookbook, Bakery üzerinde arama ve denetleyici test Mark Story'nin ilanları okumak (hard way ve {[(3) ilgili bölümleri okudum ]}).

Ne yazık ki, bunların hiçbiri olmayan önemsiz denetleyicileri gerçek dünya testleri bahsediyor. Apps sürü bir giriş arkasında site alanları koymak, ama ben basit senaryoyu test için nasıl bilemiyorum:

  • korumalı sayfaya konuk erişimi yönlendirir?
  • Geçerli kimlik setleri oturum değişkenleri bekleniyor?
  • Geçersiz kimlik bilgileri yeniden görüntüler bir hata mesajı ile giriş sayfasını?

Ben düşündüm gibi denetleyici ve aşağıdaki testi işe yaramaz. Hem iddialar başarısız ve ben de bir PHP hatası alıyorum:

FAILED [NULL] should not be null at [.../app/tests/cases/controllers/users_controller.test.php line 79] .../app/tests/cases/controllers/users_controller.test.php -> UsersControllerTest -> testLogin

FAILED Equal expectation fails as [NULL] does not match [Integer: 1] at [.../app/tests/cases/controllers/users_controller.test.php line 80] .../app/tests/cases/controllers/users_controller.test.php -> UsersControllerTest -> testLogin

ERROR Unexpected PHP error [Undefined index: action] severity [E_NOTICE] in [.../cake/libs/controller/components/auth.php line 266] .../app/tests/cases/controllers/users_controller.test.php -> UsersControllerTest -> testLogin

İşte denetleyicisi (pişmiş artı Mark Story "sert bir şekilde" test metodu):

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

İşte test:

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

1 Cevap

Eğer varsa testi UsersContoller test, gerçekten AuthComponent test ediyoruz gerçekten değil. Bunu yapmak istiyorsanız bu sizin app olacak gibi emin kurulumu TestUsersController aynı yapmanız gerekir. Lütfen testLogin bir durumda denetleyicisinin eylem ve url ayarlamanız gerekir:

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

Alternatif olarak, ben Mark's mock objects post başka bir göz alarak ve denetleyici kodu testleri yazmak için bu yöntemleri kullanarak ve auth bileşeni alaycı öneririm.