Last active
December 10, 2015 13:59
-
-
Save real34/4444502 to your computer and use it in GitHub Desktop.
Extended CakePHP test case class with convenience methods
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "occitech/occitech-test-case", | |
"description": "Occitech custom Test Case base", | |
"keywords": ["cakephp","test"], | |
"homepage": "http://www.occitech.fr", | |
"license": "MIT", | |
"authors": [ | |
{ | |
"name": "Occitech", | |
"homepage": "http://www.occitech.fr" | |
} | |
], | |
"require": { | |
"php": ">=5.3.0" | |
}, | |
"autoload": { | |
"classmap": ["."] | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
App::uses('ControllerTestCase', 'TestSuite'); | |
/** | |
* Occitech custom Test Library. | |
* Extends core librairy to add convenience methods. | |
*/ | |
abstract class OccitechCakeTestCase extends ControllerTestCase { | |
protected $fixtures = array(); | |
/** | |
* First record from fixtures | |
* | |
* @var array | |
*/ | |
protected $_record = array(); | |
public function setUp() { | |
parent::setUp(); | |
if ($this->__isPluginTest()) { | |
Configure::write('listenersDependencies', array()); | |
} | |
} | |
private function __isPluginTest() { | |
$isPluginTest = !empty($this->fixtures); | |
foreach ($this->fixtures as $fixture) { | |
$isPluginTest = $isPluginTest && strpos($fixture, 'plugin') === 0; | |
} | |
return $isPluginTest; | |
} | |
/** | |
* Asserts that data are valid given Model validation rules | |
* Calls the Model::validate() method and asserts the result | |
* | |
* @param Model $Model Model being tested | |
* @param array $data Data to validate | |
* @return void | |
*/ | |
public function assertValid(Model $Model, $data, $restrictFields = false) { | |
$isValid = $this->_validData($Model, $data, $errors, $restrictFields); | |
$this->assertTrue($isValid, 'Validation fails'); | |
} | |
/** | |
* Asserts that data are validation errors match an expected value when | |
* validation given data for the Model | |
* Calls the Model::validate() method and asserts validationErrors | |
* | |
* @param Model $Model Model being tested | |
* @param array $data Data to validate | |
* @param array $expectedErrors Expected errors keys | |
* @return void | |
*/ | |
public function assertValidationErrors($Model, $data, $expectedErrors, $restrictFields = false) { | |
$isValid = $this->_validData($Model, $data, $validationErrors, $restrictFields); | |
$this->assertFalse($isValid, 'Validation does not fail'); | |
sort($expectedErrors); | |
$this->assertEquals($expectedErrors, array_keys($validationErrors), 'Validation errors do not match'); | |
} | |
/** | |
* Convenience method allowing to validate data and return the result | |
* | |
* @param Model $Model Model being tested | |
* @param array $data Profile data | |
* @param array $validationErrors Validation errors: this variable will be updated with validationErrors (sorted by key) in case of validation fail | |
* @return boolean Return value of Model::validate() | |
*/ | |
protected function _validData(Model $Model, $data, &$validationErrors = array(), $restrictFields = false) { | |
$valid = true; | |
$validateOptions = array(); | |
if ($restrictFields) { | |
$validateOptions['fieldList'] = array_keys($data); | |
} | |
$Model->create($data); | |
if (!$Model->validates($validateOptions)) { | |
$validationErrors = $Model->validationErrors; | |
ksort($validationErrors); | |
$valid = false; | |
} else { | |
$validationErrors = array(); | |
} | |
return $valid; | |
} | |
/** | |
* Execute a search, return the result ids and generated conditions | |
* | |
* @param Model $Model Model being tested | |
* @param array $criteria Search criteria | |
* @param array $conditions (Out) search conditions used | |
* @return array List of result ids in the returned order | |
*/ | |
protected function _searchResults(Model $Model, $criteria, &$conditions = array()) { | |
$conditions = $Model->parseCriteria($criteria); | |
$results = $Model->find('all', compact('conditions')); | |
return Hash::extract($results, '{n}.' . $Model->alias . '.id'); | |
} | |
/** | |
* Assert results of a search with criteria | |
* | |
* @param Model $Model Model being tested | |
* @param array $criteria Search criteria | |
* @param array $expected Expected id | |
*/ | |
protected function _assertSearchResults(Model $Model, $criteria, $expected) { | |
$results = $this->_searchResults($Model, $criteria, $conditions); | |
sort($expected); | |
sort($results); | |
$this->assertEqual($results, $expected); | |
} | |
/** | |
* Expects that an event is dispatched once with the correct params passed | |
* The event propagation will be stopped by default (see $stopEvent param) | |
* | |
* @param string $eventName Name of the expected event | |
* @param Object $expectedSubject PHPUnit constraint for the event subject (like used for a with) | |
* @param Object $expectedParams PHPUnit constraint for the additional params | |
* @param boolean $stopEvent Set to false to keep event propagation | |
* @param Object $nbCalls Number of expected calls, optional [default: $this->once()] | |
* @param Object $eventManager Event manager waiting the event | |
* @return callable Attached callback so you can detach it afterwards | |
* $callback = $this->expectDispatchedEvent([...]); | |
* [ trigger the event ] | |
* CakeEventManager::instance()->detach($callback); | |
*/ | |
public function expectEventDispatched($eventName, $expectedSubject = null, $expectedParams = null, $stopEvent = true, $nbCalls = null, $eventManager = null) { | |
if (is_null($expectedSubject)) { | |
$expectedSubject = $this->anything(); | |
} | |
if (is_null($expectedParams)) { | |
$expectedParams = $this->anything(); | |
} | |
if (is_null($nbCalls)) { | |
$nbCalls = $this->once(); | |
} | |
if (is_null($eventManager)) { | |
$eventManager = CakeEventManager::instance(); | |
} | |
$Listener = $this->getMock('StdObject', array('callbackMethod')); | |
$callback = function($event) use ($Listener, $stopEvent) { | |
$Listener->callbackMethod($event->subject(), $event->data); | |
if ($stopEvent) { | |
$event->stopPropagation(); | |
} | |
}; | |
$eventManager->attach($callback, $eventName, array('priority' => 1)); | |
if ($eventManager !== CakeEventManager::instance()) { | |
$this->detachEvent($eventName); | |
} | |
$Listener->expects($nbCalls)->method('callbackMethod') | |
->with($expectedSubject, $expectedParams); | |
return $callback; | |
} | |
public function detachEvent($eventName) { | |
CakeEventManager::instance()->detach(null, $eventName); | |
foreach(CakeEventManager::instance()->listeners($eventName) as $listner) { | |
CakeEventManager::instance()->detach($listner['callable'], $eventName); | |
} | |
} | |
/** | |
* Expects that an event is never dispatched | |
* The event propagation will be stopped by default (see $stopEvent param) | |
* | |
* @param string $eventName Name of the expected event | |
* @param boolean $stopEvent Set to false to keep event propagation | |
* @return callable Attached callback so you can detach it afterwards | |
*/ | |
public function expectEventNotDispatched($eventName, $stopEvent = true) { | |
$Listener = $this->getMock('StdObject', array('callbackMethod')); | |
$callback = function($event) use ($Listener, $stopEvent) { | |
$Listener->callbackMethod(); | |
if ($stopEvent) { | |
$event->stopPropagation(); | |
} | |
}; | |
CakeEventManager::instance()->attach($callback, $eventName, array('priority' => 1)); | |
$Listener->expects($this->never())->method('callbackMethod'); | |
return $callback; | |
} | |
public function assertDateWithinMargin($expected, $result, $margin, $message = '') { | |
$upper = strtotime($expected . '+' . $margin); | |
$lower = strtotime($expected . '-' . $margin); | |
$result = strtotime($result); | |
return self::assertTrue((($result <= $upper) && ($result >= $lower)), $message); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment