0

私はCakePHP 2.4を使用しています

Storybook という Model クラスがあります。

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 にユーザー データを入力できません。

お知らせ下さい。

4

1 に答える 1

3

グーグルで#cakephp IRCチャネルを尋ねた後、私が見つけた手順:

1) 少なくとも CakePHP 2.3 を使用していることを確認してください

2) AppModel で次の保護された関数を作成します。

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

3) AppModel 内で AuthComponent が実際に使用されていることを確認します。

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

4) AuthComponent::user の代わりに _getUser を使用するように Storybook モデルを変更します。

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

5) このドキュメントの厚意により、テスト メソッドに以下を追加します。

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

それはあなたが試験に合格するのに役立ちます。

アップデート

モックしているメソッドが異なるパラメーターに応じて異なる結果を返す可能性がある場合は、モックされたメソッドのコールバックとして機能する別のパブリック関数が必要です。

ステップ 5 の代替) パラメータが「id」の場合は常に 23 を返し、パラメータが「group_id」の場合は 1 を返すと予想される場合は、次の関数を追加します。

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

PHPunit のマッチャーの有用なリスト。例えば

$this->once()
$this->never()
于 2013-10-02T10:23:32.360 に答える