1

次のコードを使用して、UsersController のログイン アクションをテストしています。

public function testLogin() {
    $data = array('User' => array(
                'username' => 'hello',
                'password' => '411'
                    )
            );
    $this->Users = $this->generate('Users',array('components'=> array('Auth','Session')));
    $this->Users->Auth->staticExpects($this->once())
                        ->method('user')
                        ->with('id');
    $this->testAction('/users/login', array('data' => $data, 'method' => 'post'));

}

そしてフィクスチャは-

class UserFixture extends CakeTestFixture {
    public $import = array('model' => 'User', 'records' => true, 'connection' => 'fixture');
}

そしてアクションは-

public function login() {

        if($this->request->is('post')) {
            if($this->Auth->login()) {
                $this->redirect($this->Auth->redirect());
            } else {
                return false;
                $this->Session->setFlash(__('Wrong Username Or Password,Please Try Again'));
            }
        }
    }

いつも見せてる

メソッド名の期待に失敗しましたが、1 回呼び出されたときと同じです。メソッドは 1 回呼び出されると予想されていましたが、実際には 0 回呼び出されました。

何が問題なのですか?解決策が見つかりません。理由も教えてください。助けてください。

4

2 に答える 2

2

認証コンポーネントをモックする問題は、コンポーネント配列に含めることに加えて、authモックする Auth のメソッドとそれらをモックする方法を指定する必要があることだと思います。

テストで AuthComponent を処理する方法は、メソッドを使用してスーパークラスを作成することです。_generateMockWithAuthUserIdこれは、特に必要な方法で Auth コンポーネントをモックします。

スーパークラスのコードを以下に貼り付けました。

class AppControllerTest extends ControllerTestCase {

    public function setUp() {
        parent::setUp();
        $this->User = ClassRegistry::init('User');
    }

    public function tearDown() {
        unset($this->User);
        parent::tearDown();
    }

    public function testPlaceholder(){
        // This just here so we don't get "Failed - no tests found in class AppControllerTest"
        $this->assertTrue(true);
    }

    protected function _generateMockWithAuthUserId($contollerName, $UserId){
        $this->authUserId = $UserId;
        $this->authUser = $this->User->findById($this->authUserId);
        $this->controller = $this->generate($contollerName, array(
            'methods' => array(
                '_tryRememberMeLogin',
                '_checkSignUpProgress'
            ),
            'components' => array(
                'Auth' => array(
                    'user',
                    'loggedIn',
                ),
                'Security' => array(
                    '_validateCsrf',
                ),
                'Session',
            )
        ));

        $this->controller->Auth
            ->expects($this->any())
            ->method('loggedIn')
            ->will($this->returnValue(true));

        $this->controller->Auth
            ->staticExpects($this->any())
            ->method('user')
            ->will($this->returnCallback(array($this, 'authUserCallback')));

    }

    public function authUserCallback($param){
        if(empty($param)){
            return $this->authUser['User'];
        } else {
            return $this->authUser['User'][$param];
        }
    }
}

次に、そのスーパークラスを継承するクラスの例を示します。をどこでどのように呼び出すかに注意してください_generateMockWithAuthUserId。基本的に、これを行うと、適切なユーザー ID に対してモック化された Auth を使用して適切なコントローラーがセットアップされます。

<?php
require_once dirname(__FILE__) . DS . 'AppControllerTest.php';

class EmployeeNotesControllerTestCase extends AppControllerTest {

    public $fixtures = array(
        // your fixtures go here
    );

    public function setUp() {
        parent::setUp();
        $this->EmployeeNote = ClassRegistry::init('EmployeeNote');
    }

    public function tearDown() {
        unset($this->EmployeeNote);
        parent::tearDown();
    }

    public function testSupervisorIndexCanNotSeeNotesOnSelf() {
        $authUserId = 1;
        $this->_generateMockWithAuthUserId('EmployeeNotes', $authUserId);

        $this->controller->Session
                ->expects($this->once())
                ->method('setFlash');

        $result = $this->testAction('supervisor/employee_notes/index/'.$authUserId, array('return' => 'vars', 'method' => 'get'));

        $this->assertTrue(empty($result['employeeNotes']));
    }
}

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

于 2013-08-14T12:57:14.853 に答える
0

解決策を見つけました。うまくいきました。

public function testLogin() {
    $data = array('User' => array(
            'username' => 'sasa',
            'password' => '111'
            )
        );
    $this->Users = $this->generate('Users', array());
    $result = $this->testAction('/users/login', array('data' => $data, 'method' => 'post'));

    $this->assertEquals($data['User']['username'],$this->Users->Session->read('Auth.User.username'));
    $result = $this->testAction('/users/logout');
}
于 2013-08-16T05:19:09.010 に答える