2

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

4 に答える 4

1

これは、たとえば、セッション データが期待どおりでない場合にログイン ページにリダイレクトする認証コードによってリダイレクトされている場合に発生する可能性があります。テストで必要な環境をセットアップしていない場合は、リダイレクトされます。これは、次の値を確認することで確認できます$this->headers

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

それをテストに入れて のようなものが表示された場合はarray('Location' => 'your_login_page')、テスト環境に、認証システム (またはリダイレクトを挿入する可能性のあるその他のもの) を維持するために必要なすべてが含まれていることを確認してください。

于 2016-02-17T00:22:37.320 に答える
0

単体テストの実行を計画している場合は、個々の単体のテストを検討する必要があります。そうは言っても、CakePHP に統合された PHPUnit はかなり堅牢で、データやメソッドのモックなど、必要なものを提供できます。

単体テストを作成すると、次のようになります。

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

これにより、ビュー、データベース アクセスなどを含む統合テストを実行せずに、作成された値に対してテストできます。

これが役立つことを願っています。: )

于 2013-08-13T05:44:49.470 に答える
0

$this->testAction の結果を取得し、何を返すかを指定する必要があります ( http://book.cakephp.org/2.0/en/development/testing.html#testing-controllers )

例えば

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

debug($result);
于 2012-05-25T15:51:01.853 に答える
-1

問題の原因はわかっていると思います。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 です。つまり、articles/view/1 に「投稿」しても何も得られません。

于 2012-06-18T01:49:44.203 に答える