2013-10-18 2 views
-1

저는 내 컨트롤러 중 하나에 대해 CakePHP 유닛 테스트를 작성하고 있습니다. 컨트롤러에는 AuthComponent::user() 메서드에 대한 호출이 여러 개있어 현재 로그인 한 사용자의 데이터를 읽습니다. 3 개 용도가 있습니다CakePHP에서 인증 된 사용자 조롱하기

  • AuthComponent::user() 나는 두 가지를 시도
  • AuthComponent::user('id')
  • 가 (사용자 ID를 가져옵니다)
  • AuthComponent::user('name')가 (사용자 이름을 가져옵니다)

(매개 변수없이이 전체 배열을 가져옵니다)

// Mock the Controller and the Components 
$this->controller = $this->generate('Accounts', array(
    'components' => array(
     'Session', 'Auth' => array('user'), 'Acl' 
    ) 
)); 

// Method 1, write the entire user array 
$this->controller->Auth->staticExpects($this->any())->method('user') 
    ->will($this->returnValue(array(
     'id' => 2, 
     'username' => 'admin', 
     'group_id' => 1 
    ))); 

// Method 2, specifically mock the AuthComponent::user('id') method 
$this->controller->Auth->staticExpects($this->any())->method('user') 
    ->with('id') 
    ->will($this->returnValue(2)); 

살전 : 내 테스트에 AuthComponent을 조롱하는 방법 그래도 e 방법은 저를 위해 작동하지 않습니다. 방법 1은 아무것도 수행하지 않는 것으로 보입니다. 현재 로그인 한 사용자의 ID를 사용하는 내 컨트롤러의 저장 작업이 null을 반환하므로 값이 올바르게 설정되거나 획득되지 않습니다.

방법 2 작동하는 것 같다,하지만 너무 광범위, 그것은 또한 AuthComponent::user() 호출 (PARAMS없이 일)에 자신을 바인딩을 시도하며 오류와 함께 실패합니다

Expectation failed for method name is equal to when invoked zero or more times Parameter 0 for invocation AuthComponent::user(null) does not match expected value. Failed asserting that null matches expected 'id'.

가 어떻게 적절한 얻을 수 있습니다 모든 필드/변수를 얻을 수 있도록 AuthComponent에 대한 mock?

답변

2

이것은 내가하는 방법입니다. 이 코드에서 필자는 사용자 모델로 'Employee'를 사용하고 있지만 변경하기 쉽습니다.

나는 'user'메소드에 대한 콜백을 리턴하는 AppControllerTest.php 수퍼 클래스를 가지고있다. 콜백은 params가 있거나없는 경우를 처리합니다. _generateMockWithAuthUserId은 당신이 겪은 것이지만, 모두 읽으십시오. testPlaceholder처럼 주목할 가치가있는 몇 가지 다른 것들이 있습니다.

<?php 
App::uses('Employee', 'Model'); 

/** 
* EmployeeNotesController Test Case 
* Holds common Fixture ID's and mocks for controllers 
*/ 
class AppControllerTest extends ControllerTestCase { 

    public $authUserId; 

    public $authUser; 

/** 
* setUp method 
* 
* @return void 
*/ 
    public function setUp() { 
     parent::setUp(); 
     $this->Employee = ClassRegistry::init('Employee'); 
    } 

/** 
* tearDown method 
* 
* @return void 
*/ 
    public function tearDown() { 
     unset($this->Employee); 
     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, $employeeId) { 
     $this->authUserId = $employeeId; 
     $this->authUser = $this->Employee->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['Employee']; 
     } else { 
      return $this->authUser['Employee'][$param]; 
     } 
    } 
} 

그런 다음, 내 컨트롤러 테스트 케이스가 그 클래스에서 상속 :

require_once dirname(__FILE__) . DS . 'AppControllerTest.php'; 
class EmployeeNotesControllerTestCase extends AppControllerTest { 
    // Tests go here 

을 그리고 당신은 테스트에서 인증 구성 요소를 조롱 할 때, 당신은

$this->_generateMockWithAuthUserId('EmployeeNotes', $authUserId); 
전화 여기에 내 모든 클래스의

여기서 'EmployeeNotes'는 컨트롤러의 이름이고, $ authUserId는 테스트 데이터베이스에있는 사용자의 ID입니다.

+0

감사합니다. 이것은 귀찮은 오류를 통해 나를 알아 냈으므로 모든 테스트에 대해 Auth를 조롱하는 멋진 구성입니다. 필자는 static (정적 메소드가 null을 계속 돌려 주었던) 작업을 시작하기 전에 내 정적'AuthComponent :: user' 호출을 내 컨트롤러에서'$ this-> Auth-> user' 호출로 대체했습니다. – Oldskool