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

Перейдем к 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'
        ),
         );
}

4 ответа

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

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

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

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

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

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

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

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

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

например

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

debug($result);

Я думаю, что я знаю, что вызывает проблему. Вам необходимо предоставить метод для 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 ничего не даст.

Другие вопросы по тегам