2013-10-02 5 views
0

Я использую CakePHP 2.4как проверить метод, который использует модель AuthComponent :: пользователя внутри

У меня есть класс модели под названием Storybook.

Существует метод, называемый createDraft и его код выглядит следующим образом:

public function createDraft($data) { 
     $data['Storybook']['author'] = AuthComponent::user('id'); 

Когда я пишу сценарий тестирования с помощью тестов CakePHP, у меня есть проблема экземпляра пользовательских данных внутри AuthComponent.

Мой тестовый сценарий выглядит следующим образом:

<?php 
App::uses('Storybook', 'Model'); 
class StorybookTestCase extends CakeTestCase { 

/** 
* Fixtures 
* 
* @var array 
*/ 
    public $fixtures = array(... 
    ); 

/** 
* setUp method 
* 
* @return void 
*/ 
    public function setUp() { 
     parent::setUp(); 
     $this->Storybook = ClassRegistry::init('Storybook'); 
... 
... 


/** 
* GIVEN we have only a title 
* WHEN we call createDraft 
* THEN we have a new draft 
* 
* @return void 
*/ 
    public function testCreateDraftSuccessfully() {  
     // GIVEN only a title 
     $data = array('Storybook' => array('title' => 'some title')); 
     // WHEN we call the createDraft 
     $actualResult = $this->Storybook->createDraft($data); 
.... 

тест потерпел неудачу в методе createDraft.

Я не могу заполнить AuthComponent пользовательскими данными по методу setUp, поскольку метод входа в систему AuthComponent не является статическим.

Просьба сообщить.

ответ

3

шаги я понял, после того, как какой-то прибегая к помощи и просят #cakephp IRC канал:

1) Убедитесь, что вы используете, по крайней мере CakePHP 2.3

2) создать такую ​​защищенную функцию в AppModel:

protected function _getUser($key = null) { 
    return AuthComponent::user($key); 
} 

3) гарантировать, что AuthComponent фактически используется внутри AppModel:

//type this just below App::uses('Model', 'Model'); 
App::uses('AuthComponent', 'Controller/Component'); 

4) Измените модель Storybook использовать _getUser вместо AuthComponent :: пользователя

public function createDraft($data) { 
     $data['Storybook']['author'] = $this->_getUser('id'); 

5) Добавьте следующее в метод испытания любезно этой documentation:

public function testCreateDraftSuccessfully() {  

     // MOCK the _getUser method to always return 23 because we always expect that 
     $this->Storybook = $this->getMockForModel('Storybook', array('_getUser')); 
     $this->Storybook->expects($this->once()) 
     ->method('_getUser') 
     ->will($this->returnValue(23)); 

    // GIVEN only a title 
    $data = array('Storybook' => array('title' => 'some title')); 

Это поможет вам пройти тест.

UPDATE

Если метод вы насмешливый может возвращать разные результаты в зависимости от различных параметров, вы должны иметь другую общественную функцию, которая будет выступать в качестве обратного вызова для издевался метода.

Альтернатива к шагу 5) Добавьте следующую функцию, если вы ожидаете, всегда возвращает 23, если параметр «идентификатор» и 1, если параметр «group_id»

public function getUserCallBack($field) { 
     if ($field == 'id') { 
      return 23; 
     } 
     if ($field == 'group_id') { 
      return 1; 
     } 
    } 

6) Изменение метода испытаний :

public function testCreateDraftSuccessfully() {  

     // MOCK the _getUser method to always return 23 for _getUser('id') and 1 for _getUser('group_id') 
     $this->Storybook = $this->getMockForModel('Storybook', array('_getUser')); 
     $this->Storybook->expects($this->once()) 
     ->method('_getUser') 
     ->with($this->logicalOr(
      $this->equalTo('id'), 
      $this->equalTo('group_id') 
     )) 
     ->will($this->returnCallback(array($this, 'getUserCallBack'))); 

    // GIVEN only a title 
    $data = array('Storybook' => array('title' => 'some title')); 

Useful list of matchers for PHPunit. Например:

$this->once() 
$this->never() 
Смежные вопросы