CakePHP 2.1 - Контроллеры модульного тестирования $this-›view и $this-›contents равно null

Переходим на cakephp 2.1 и только начинаем изучать модульное тестирование...

Когда я ArticlesControllerTestCase::testView()

и беги

$this->testAction('articles/view/1'); 
debug($this->view); 
debug($this->contents); 
die;

оба $this->view and $this->contents равны нулю

Я очистил вызовы beforeFilter и вызовы beforeRender, чтобы попытаться устранить это...

Я заметил, что в действии контроллера, если я устанавливаю $this->render('view'); в конце метода, я получаю $this->view = 'что это должно быть', но $this->contents = 'то же самое и не содержит макет

есть идеи, почему это происходит?

class ArticlesController extends MastersController {

    /*
     * Name
     */
    public $name = 'Articles';

    /*
     * Publicly Accessible Methods
     */
    public $allowed = array('view', 'index', 'category', 'news');


    /*
     * Default Search Params
     */
    public $presetVars = array(
        array('field' => 'title', 'type' => 'value'),
        array('field' => 'category_id', 'type' => 'value'),
        array('field' => 'status_id', 'type' => 'value'),           
    );

    /*
     * Admin Menu Options
     */
    public $adminMenu = array('index'=>array('Category'));

    /**
     * Before Filter Callback
     * (non-PHPdoc)
     * @see controllers/MastersController::beforeFilter()
     * @return void
     */
    public function beforeFilter(){
        parent::beforeFilter();
        $categories = $this->Article->Category->find('class', array('article', 'conditions'=>array('not'=>array('Category.name'=>'Content'))));
        $this->set(compact('categories'));
    }

    /**
     * View
     * @param $id
     * @see controllers/MastersController::_view()
     * @return void
     */
    public function view($id){
        parent::_view($id);
        $articleTitle = $this->Article->findField($id,'title');
        $recentNews = $this->Article->find('recentNews');
        $this->set('title_for_layout', $articleTitle);
        $this->set(compact('recentNews'));
    }
};

class MastersController extends AppController {

    /*
     * Name
     */
    public $name = 'Masters'; # expected to be overridden

    /**
     * View
     * Default view method for all controllers
     * Provides an individual record based on the record id
     * @param int $id: model id
     * @return void
     */
    protected function _view($id){
        $this->Redirect->idEmpty($id, array('action'=>'index'));
        ${Inflector::singularize($this->request->params['controller'])} = $this->{$this->modelClass}->find('record', array($id));
        ${Inflector::variable(Inflector::singularize($this->request->params['controller']))} = ${Inflector::singularize($this->request->params['controller'])};

        if(empty(${Inflector::singularize($this->request->params['controller'])})){
            return $this->Redirect->flashWarning('Invalid Id.', $this->referer());
        }       
        $this->set(compact(Inflector::singularize($this->request->params['controller']), Inflector::variable(Inflector::singularize($this->request->params['controller']))));
    }
}


class ArticlesControllerTestCase extends ControllerTestCase {

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

    /**
     * Set Up
     *
     * @return void
     */
    public function setUp() {
        parent::setUp();
        $this->Articles = new TestArticlesController();
        $this->Articles->constructClasses();
    }

    /**
     * Tear Down
     *
     * @return void
     */
    public function tearDown() {
        unset($this->Articles);

        parent::tearDown();
    }

    /**
     * Test View
     *
     * @return void
     */
    public function testView() {
        $this->testAction('articles/view/1');
        debug($this->view); die;
    }
}


class ArticleFixture extends CakeTestFixture {

    /**
     * Fields
     *
     * @var array
     */
    public $fields = array(
        'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
        'slug' => array('type' => 'string', 'null' => true, 'default' => NULL, 'length' => 120, 'collate' => 'latin1_swedish_ci', 'charset' => 'latin1'),
        'title' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 100, 'collate' => 'latin1_swedish_ci', 'charset' => 'latin1'),
        'body' => array('type' => 'text', 'null' => false, 'default' => NULL, 'collate' => 'latin1_swedish_ci', 'charset' => 'latin1'),
        'created' => array('type' => 'datetime', 'null' => false, 'default' => NULL),
        'modified' => array('type' => 'datetime', 'null' => false, 'default' => NULL),
        'status_id' => array('type' => 'integer', 'null' => false, 'default' => NULL),
        'category_id' => array('type' => 'integer', 'null' => false, 'default' => NULL),
        'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),
        'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB')
    );

    /**
     * Records
     *
     * @var array
     */
    public $records = array(
        array(
            'id' => '1',
            'slug' => NULL,
            'title' => 'Test Article #1 without slug - published',
            'body' => '<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p><p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>',
            'created' => '2011-02-15 21:14:03',
            'modified' => '2011-02-15 21:14:03',
            'status_id' => '1',
            'category_id' => '5'
        ),
         );
}

person devnull    schedule 17.05.2012    source источник
comment
$this относится не к вашему контроллеру, а к вашему тестовому примеру.   -  person pixelistik    schedule 25.05.2012


Ответы (4)


Это может произойти, если вас перенаправляет, например, какой-то код аутентификации, который перенаправляет на страницу входа, если данные сеанса не соответствуют ожидаемым. Если вы не настроили необходимую среду в своих тестах, вы будете перенаправлены. Вы можете проверить это, проверив значение $this->headers:

debug("Headers: " . print_r($this->headers));

Если вы поместите это в свой тест и увидите что-то вроде array('Location' => 'your_login_page'), убедитесь, что ваша тестовая среда включает все необходимое, чтобы ваша система аутентификации (или что-либо еще, что может вставлять перенаправления) работало.

person cincodenada    schedule 17.02.2016

Вам нужно зафиксировать результат $this->testAction и указать, что вы хотите вернуть ( http://book.cakephp.org/2.0/en/development/testing.html#testing-controllers )

e.g.

$result = $this->testAction('articles/view/1', array('return'=>'content'));

debug($result);
person RichardAtHome    schedule 25.05.2012
comment
Я столкнулся с этой проблемой. Предоставление возврата все равно приведет к нулю, если только article/view/1 не примет почтовый запрос. опция method=get должна быть указана в testAction() - person wenbert; 18.06.2012

Если вы планируете выполнять модульное тестирование, вам действительно следует проверить каждую отдельную единицу. При этом PHPUnit, когда он интегрирован в CakePHP, достаточно надежен и может предоставить такие вещи, которые вам нужны, такие как имитация данных и методов.

Когда я пишу модульный тест, он выглядит примерно так:

function testSomeTestCaseWithDescriptiveMethodName(){
    $this->testAction("controller/action/arguments");
    $this->assertEqual([some value or data set], $this->vars["key"];
}

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

Надеюсь, это поможет. :)

person Chris Stead    schedule 13.08.2013

Кажется, я знаю, в чем причина проблемы. Вам нужно указать метод для testAction().

$this->testAction('articles/view/1', array('method'=>'get')); 
debug($this->view); //should output the view
debug($this->contents);  //should output the contents

ИМХО, документы (http://book.cakephp.org/2.0/en/development/testing.html#testing-controllers) делают вид, что по умолчанию используется GET. На самом деле по умолчанию используется POST, поэтому «публикация» в article/view/1 ничего не даст.

person wenbert    schedule 18.06.2012
comment
также попробуйте отладить ($this-›headers) — чтобы проверить, не были ли вы перенаправлены со страницы - person wenbert; 18.06.2012
comment
по-прежнему устанавливается как null... если я устанавливаю $this-›render('view'); в действии контроллера, тогда $this-›view/$this-›contents установлены правильно. Однако мне не нужно этого делать... и debug($this-›headers) по-прежнему остается пустым массивом. Я должен понять это в ближайшее время, отстаю от этого проекта. - person devnull; 19.06.2012
comment
Заголовки $this-›будут пустыми, если вы не были перенаправлены. Если у вас есть $this-›view / $this-›contents, то вы должны просто делать утверждения по этим ИМХО.... Я новичок в CakePHP - если у вас есть дополнительные вопросы, то #cakephp в freenode также отличный способ спросить у людей... - person wenbert; 19.06.2012