Commit 01c3f715 authored by Ivan Chepurnyi's avatar Ivan Chepurnyi

! closes feature #56 "Set mock to Magento factories"

! closes feature #55 "Create mock by class alias"
parent d6d016a1
......@@ -32,6 +32,9 @@ class EcomDev_PHPUnit_Model_App extends Mage_Core_Model_App
// Admin store code
const ADMIN_STORE_CODE = 'admin';
const REGISTRY_PATH_LAYOUT_SINGLETON = '_singleton/core/layout';
const XML_PATH_LAYOUT_MODEL_FOR_TEST = 'phpunit/suite/layout/model';
/**
* Old configuration model to be returned back
* after unit tests are finished
......@@ -122,8 +125,15 @@ class EcomDev_PHPUnit_Model_App extends Mage_Core_Model_App
*/
public function initTest()
{
if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
// If garbage collector is not enabled,
// we enable it for tests
if (!gc_enabled()) {
gc_enable();
}
}
$this->_config = Mage::getConfig();
$this->_config->setOptions($options);
$this->_initBaseConfig();
$this->_initCache();
......@@ -152,6 +162,12 @@ class EcomDev_PHPUnit_Model_App extends Mage_Core_Model_App
Mage_Core_Model_Resource_Setup::applyAllDataUpdates();
}
$layoutModel = Mage::getModel(
$this->getConfig()->getNode(self::XML_PATH_LAYOUT_MODEL_FOR_TEST)
);
Mage::register(self::REGISTRY_PATH_LAYOUT_SINGLETON, $layoutModel, true);
return $this;
}
......
......@@ -31,6 +31,13 @@ class EcomDev_PHPUnit_Model_Config extends Mage_Core_Model_Config
*/
protected $_scopeSnapshot = null;
/**
* List of replaced instance creation
*
* @return array
*/
protected $_replaceInstanceCreation = array();
/**
* Load config data from DB
*
......@@ -47,6 +54,62 @@ class EcomDev_PHPUnit_Model_Config extends Mage_Core_Model_Config
return $this;
}
/**
* Replaces creation of some instance by mock object
*
*
* @param string $type
* @param string $classAlias
* @param PHPUnit_Framework_MockObject_MockObject|PHPUnit_Framework_MockObject_MockBuilder $mock
* @return EcomDev_PHPUnit_Model_Config
*/
public function replaceInstanceCreation($type, $classAlias, $mock)
{
$this->_replaceInstanceCreation[$type][$classAlias] = $mock;
return $this;
}
/**
* Flushes instance creation instruction list
*
* @return EcomDev_PHPUnit_Model_Config
*/
public function flushReplaceInstanceCreation()
{
$this->_replaceInstanceCreation = array();
return $this;
}
/**
* Overriden for test case model instance creation mocking
*
* (non-PHPdoc)
* @see Mage_Core_Model_Config::getModelInstance()
*/
public function getModelInstance($modelClass='', $constructArguments=array())
{
if (!isset($this->_replaceInstanceCreation['model'][$modelClass])) {
return parent::getModelInstance($modelClass='', $constructArguments=array());
}
return $this->_replaceInstanceCreation['model'][$modelClass];
}
/**
* Overriden for test case model instance creation mocking
*
* (non-PHPdoc)
* @see Mage_Core_Model_Config::getModelInstance()
*/
public function getResourceModelInstance($modelClass='', $constructArguments=array())
{
if (!isset($this->_replaceInstanceCreation['resource_model'][$modelClass])) {
return parent::getResourceModelInstance($modelClass='', $constructArguments=array());
}
return $this->_replaceInstanceCreation['resource_model'][$modelClass];
}
/**
* Loads scope snapshot
*
......
<?php
// Loading Spyc yaml parser,
// becuase Symfony component is not working propertly with nested
require_once 'Spyc/spyc.php';
class EcomDev_PHPUnit_Model_Expectation
implements EcomDev_PHPUnit_Model_Expectation_Interface
{
/**
* List of created data object ids by path format
*
* @var array
*/
protected $_dataObjectIds = array();
/**
* Loaded data from Yaml files
*
* @var Varien_Object
*/
protected $_loadedData = null;
/**
* Data object used for managing
* expectation data
*
* @var string
*/
protected $_dataObjectClassAlias = 'ecomdev_phpunit/expectation_object';
/**
* Returns class alias for fixture data object
*
* @return string
*/
public function getDataObjectClassAlias()
{
return $this->_dataObjectClassAlias;
}
/**
* Retrieves data object for a particular path format
*
* @see EcomDev_PHPUnit_Model_Expectation_Interface::getDataObject()
*/
public function getDataObject($pathFormat = null, $args = array())
{
if ($pathFormat === null) {
return $this->_loadedData;
}
$argsHash = $pathFormat . '_' . md5(serialize($args));
// Check already created objects by path
if (!isset($this->_dataObjectIds[$argsHash])) {
if ($args) {
array_unshift($args, $pathFormat);
$dataPath = call_user_func_array('sprintf', $args);
} else {
$dataPath = $pathFormat;
}
$data = $this->_loadedData->getData($dataPath);
if (!is_array($data)) {
throw new InvalidArgumentException(
'Argument values for specifying special scope of expectations should be presented '
. ' in expectation file and should be an associative list (path: "' . $dataPath . '")'
);
}
$this->_dataObjectIds[$argsHash] = Mage::objects()->save(
Mage::getModel($this->getDataObjectClassAlias(), $data)
);
}
return Mage::objects($this->_dataObjectIds[$argsHash]);
}
/**
* Applies loaded data
*
* @see EcomDev_PHPUnit_Model_Test_Loadable_Interface::apply()
*/
public function apply()
{
// For now it does nothing :(
return $this;
}
/**
* Removes objects created in object cache
* Clears loaded data property
*
* @see EcomDev_PHPUnit_Model_Test_Loadable_Interface::discard()
*/
public function discard()
{
foreach ($this->_dataObjectIds as $objectId) {
Mage::objects()->delete($objectId);
}
$this->_dataObjectIds = array();
$this->_loadedData = null;
return $this;
}
/**
* Check that expectations is loaded
*
* @return boolean
*/
public function isLoaded()
{
return $this->_loadedData !== null;
}
/**
* Loads expected data from test case annotations
*
* @see EcomDev_PHPUnit_Model_Test_Loadable_Interface::loadByTestCase()
*/
public function loadByTestCase(EcomDev_PHPUnit_Test_Case $testCase)
{
$expectations = $testCase->getAnnotationByName('loadExpectation');
if (!$expectations) {
$expectations[] = null;
}
$expectationData = array();
foreach ($expectations as $expectation) {
if (empty($expectation)) {
$expectation = null;
}
$expectationFile = $testCase->getYamlFilePath('expectations', $expectation);
if (!$expectationFile) {
$text = 'There was no expectation defined for current test case';
if ($expectation) {
$text = sprintf('Cannot load expectation %s', $expectation);
}
throw new RuntimeException($text);
}
$expectationData = array_merge_recursive(
$expectationData, Spyc::YAMLLoad($expectationFile)
);
}
$this->_loadedData = new Varien_Object($expectationData);
return $this;
}
}
\ No newline at end of file
<?php
/**
* PHP Unit test suite for Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2011 Ecommerce Developers (http://www.ecomdev.org)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* @author Ivan Chepurnyi <ivan.chepurnyi@ecomdev.org>
*/
/**
* Interface for fixture model
* Can be used for creation of
* absolutely different implementation of fixture,
* then current one.
*
*/
interface EcomDev_PHPUnit_Model_Expectation_Interface extends EcomDev_PHPUnit_Model_Test_Loadable_Interface
{
/**
* Returns data object with expectations
*
* @param string $pathFormat
* @param array $args arguments for format function
* @return EcomDev_PHPUnit_Model_Expectation_Object
*/
public function getDataObject($pathFormat = null, $args = array());
/**
* Check is expectation loaded
*
* @return boolean
*/
public function isLoaded();
}
\ No newline at end of file
<?php
/**
* PHP Unit test suite for Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2011 Ecommerce Developers (http://www.ecomdev.org)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* @author Ivan Chepurnyi <ivan.chepurnyi@ecomdev.org>
*/
/**
* Expectation data object used for retrieving of data from expectations array
* Created to make possible iteration of expected data,
* for instance if you have list of orders
*
*/
class EcomDev_PHPUnit_Model_Expectation_Object
extends Varien_Object
implements Iterator
{
protected $_createdObjectIds = array();
/**
* Current key in iterator
*
* @var array
*/
protected $_iterationKeys = array();
/**
* If current element is an array,
* then it will be automatically wrapped by
* the same class instance as this one
*
* @see Iterator::current()
* @return null|int|string|boolean|decimal|EcomDev_PHPUnit_Model_Expectation_Object
*/
public function current()
{
if ($this->key() === null) {
return null;
}
$current = $this->_data[$this->key()];
if (is_array($current)) {
$newObject = new self($current);
$this->_createdObjectIds = Mage::objects()
->save($current);
return $newObject;
}
return $current;
}
/* (non-PHPdoc)
* @see Iterator::key()
*/
public function key()
{
return current($this->_iterationKeys);
}
/* (non-PHPdoc)
* @see Iterator::next()
*/
public function next()
{
next($this->_iterationKeys);
}
/* (non-PHPdoc)
* @see Iterator::rewind()
*/
public function rewind()
{
$this->_iterationKeys = $this->keys();
}
/* (non-PHPdoc)
* @see Iterator::valid()
*/
public function valid()
{
return key($this->_iterationKeys) !== null;
}
/**
* Object destructor removes
* created objects from object pool
*
*
*/
public function __destruct()
{
if (!empty($this->_createdObjectIds)) {
foreach ($this->_createdObjectIds as $objectId) {
Mage::objects()->delete($objectId);
}
}
}
/**
* Returns data array keys
*
* @return array
*/
public function keys()
{
return array_keys($this->_data);
}
/**
* Returns data array values
*
* @return array
*/
public function values()
{
return array_values($this->_data);
}
}
......@@ -26,7 +26,9 @@ require_once 'Spyc/spyc.php';
* Created for operations with different fixture types
*
*/
class EcomDev_PHPUnit_Model_Fixture extends Mage_Core_Model_Abstract
class EcomDev_PHPUnit_Model_Fixture
extends Mage_Core_Model_Abstract
implements EcomDev_PHPUnit_Model_Fixture_Interface
{
// Configuration path for eav loaders
const XML_PATH_FIXTURE_EAV_LOADERS = 'phpunit/suite/fixture/eav';
......@@ -114,6 +116,36 @@ class EcomDev_PHPUnit_Model_Fixture extends Mage_Core_Model_Abstract
return $this;
}
/**
* Loads fixture from test case annotations
*
* @param EcomDev_PHPUnit_Test_Case $testCase
* @return EcomDev_PHPUnit_Model_Fixture
*/
public function loadByTestCase(EcomDev_PHPUnit_Test_Case $testCase)
{
$fixtures = $testCase->getAnnotationByName(
'loadFixture',
array('class', 'method')
);
foreach ($fixtures as $fixture) {
if (empty($fixture)) {
$fixture = null;
}
$filePath = $testCase->getYamlFilePath('fixtures', $fixture);
if (!$filePath) {
throw new RuntimeException('Unable to load fixture for test');
}
$this->loadYaml($filePath);
}
return $this;
}
/**
* Load YAML file
*
......
<?php
/**
* PHP Unit test suite for Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2011 Ecommerce Developers (http://www.ecomdev.org)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* @author Ivan Chepurnyi <ivan.chepurnyi@ecomdev.org>
*/
/**
* Interface for fixture model
* Can be used for creation of
* absolutely different implementation of fixture,
* then current one.
*
*/
interface EcomDev_PHPUnit_Model_Fixture_Interface extends EcomDev_PHPUnit_Model_Test_Loadable_Interface
{
/**
* Sets fixture options
*
* @param array $options
* @return EcomDev_PHPUnit_Model_Fixture_Interface
*/
public function setOptions(array $options);
}
\ No newline at end of file
<?php
/**
* PHP Unit test suite for Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2011 Ecommerce Developers (http://www.ecomdev.org)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* @author Ivan Chepurnyi <ivan.chepurnyi@ecomdev.org>
*/
/**
* Layout model that adds additional functionality
* for testing the layout itself
*
*/
class EcomDev_PHPUnit_Model_Layout extends Mage_Core_Model_Layout
{
/**
* List of replaced blocks creation
*
* @return array
*/
protected $_replaceBlockCreation = array();
/**
* Replaces creation of some block by mock object
*
* @param string $classAlias
* @param PHPUnit_Framework_MockObject_MockObject|PHPUnit_Framework_MockObject_MockBuilder $mock
* @return EcomDev_PHPUnit_Model_Layout
*/
public function replaceBlockCreation($classAlias, $mock)
{
$this->_replaceBlockCreation[$classAlias] = $mock;
return $this;
}
/**
* Flushes instance creation instruction list
*
* @return EcomDev_PHPUnit_Model_Layout
*/
public function flushReplaceBlockCreation()
{
$this->_replaceBlockCreation = array();
return $this;
}
/**
* Overriden for possibility of replacing a block by mock object
* (non-PHPdoc)
* @see Mage_Core_Model_Layout::_getBlockInstance()
*/
protected function _getBlockInstance($block, array $attributes=array())
{
if (!isset($this->_replaceBlockCreation[$block])) {
return parent::_getBlockInstance($block, $attributes);
}
return $this->_replaceBlockCreation[$block];
}
/**
* Resets layout instance properties
*
* @return EcomDev_PHPUnit_Model_Layout
*/
public function reset()
{
$this->setXml(simplexml_load_string('<layout/>', $this->_elementClass));
$this->_update = Mage::getModel('core/layout_update');
$this->_area = null;
$this->_helpers = array();
$this->_directOutput = false;
$this->_output = array();
foreach ($this->_blocks as $block) {
// Remove references between blocks
$block->setParentBlock(null);
$block->setMessageBlock(null);
$block->unsetChildren();
}
$this->_blocks = array();
$this->flushReplaceBlockCreation();
return $this;
}
}
<?php
/**
* PHP Unit test suite for Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2011 Ecommerce Developers (http://www.ecomdev.org)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* @author Ivan Chepurnyi <ivan.chepurnyi@ecomdev.org>
*/
/**
* Interface for loadable test environment data
*
*/
interface EcomDev_PHPUnit_Model_Test_Loadable_Interface
{
/**
* Loads external data by test case instance
*
* @param EcomDev_PHPUnit_Test_Case $testCase
* @return EcomDev_PHPUnit_Model_Test_Loadable_Interface
*/
public function loadByTestCase(EcomDev_PHPUnit_Test_Case $testCase);
/**
* Applies external data
*
* @return EcomDev_PHPUnit_Model_Test_Loadable_Interface
*/
public function apply();
/**
* Reverts applied data
*
* @return EcomDev_PHPUnit_Model_Test_Loadable_Interface
*/
public function discard();
}
......@@ -27,10 +27,23 @@ require_once 'Spyc/spyc.php';
*/
abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
{
const XML_PATH_DEFAULT_FIXTURE_MODEL = 'phpunit/suite/fixture/model';
const XML_PATH_DEFAULT_EXPECTATION_MODEL = 'phpunit/suite/expectatio/model';
/**
* List of system registry values replaced by test case
*
* @var array
*/
protected $_replacedRegistry = array();
/**
* The expectations for current test are loaded here
*
* @var Varien_Object|null
* @deprecated since 0.2.0
*/
protected $_expectations = null;
......@@ -42,93 +55,402 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
*/
protected $_originalStore = null;
/**
* Retrieves annotation by its name from different sources (class, method)
*
*
* @param string $name
* @param array|string $sources
* @return array
*/
public function getAnnotationByName($name, $sources = 'method')
{
if (is_string($sources)) {
$source = array($sources);
}
$allAnnotations = $this->getAnnotations();
$annotation = array();
// Walkthrough sources for annotation retrieval
foreach ($sources as $source) {
if (isset($allAnnotations[$source][$name])) {
$annotation = array_merge(
$allAnnotations[$source][$name],
$annotation
);
}
}
return $annotation;
}
/**
* Loads expectations for current test case
*
* @throws RuntimeException if no expectation was found
* @return Varien_Object
* @deprecated since 0.2.0, use self::expected() instead.
*/
protected function _getExpectations()
{
if ($this->_expectations === null) {
$annotations = $this->getAnnotations();
if (isset($annotations['method']['loadExpectation'])) {
// Load expectation by annotations
$expectations = array();
foreach ($annotations['method']['loadExpectation'] as $expectation) {
if (empty($expectation)) {
$expectation = null;
}
$expectationFile = $this->_getYamlFilePath('expectations', $expectation);
if ($expectationFile) {
$expectations = array_merge_recursive(
$expectations, Spyc::YAMLLoad($expectationFile)
);
} else {
$text = 'There was no expectation defined for current test case';
if ($expectation) {
$text = sprintf('Cannot load expectation %s', $expectation);
}
throw new RuntimeException($test);
}
}
} else {
// Load expectations by test name
$expectationFile = $this->_getYamlFilePath('expectations');
if ($expectationFile) {
$expectations = Spyc::YAMLLoad($expectationFile);
} else {
throw new RuntimeException('There was no expectation defined for current test case');
}
}
$arguments = func_get_args();
return $this->expected($arguments);
}
$this->_expectations = new Varien_Object($expectations);
/**
* Replaces Magento resource by mock object
*
*
* @param string $type
* @param string $classAlias
* @param PHPUnit_Framework_MockObject_MockObject|PHPUnit_Framework_MockObject_MockBuilder $mock
* @return EcomDev_PHPUnit_Test_Case
*/
protected function replaceByMock($type, $classAlias, $mock)
{
if ($mock instanceof PHPUnit_Framework_MockObject_MockBuilder) {
$mock = $mock->getMock();
} elseif (!$mock instanceof PHPUnit_Framework_MockObject_MockObject) {
throw PHPUnit_Util_InvalidArgumentHelper::factory(
1, 'PHPUnit_Framework_MockObject_MockObject'
);
}
$arguments = func_get_args();
if ($arguments) {
if (count($arguments) > 1) {
$dataKey = call_user_func_array('sprintf', $arguments);
} else {
$dataKey = array_shift($arguments);
}
$dataPart = $this->_expectations->getData($dataKey);
if (!is_array($dataPart)) {
throw new InvalidArgumentException(
'Argument values for specifying special scope of expectations should be presented '
. ' in expectation file and should be an associative list (dataKey: "' . $dataKey . '")'
);
}
if ($type == 'helper' && strpos($classAlias, '/') === false) {
$classAlias .= '/data';
}
if (in_array($type, array('model', 'resource_model'))) {
Mage::getConfig()->replaceInstanceCreation($type, $classAlias, $mock);
$type = str_replace('model', 'singleton', $type);
} elseif ($type == 'block') {
Mage::app()->getLayout()->replaceBlockCreation($classAlias, $mock);
}
if (in_array($type, array('singleton', 'resource_singleton', 'helper'))) {
$registryPath = '_' . $type . '/' . $classAlias;
$this->replaceRegistry($registryPath, $mock);
}
return $this;
}
/**
* Replaces value in Magento system registry
*
* @param string $key
* @param mixed $value
*/
protected function replaceRegistry($key, $value)
{
$oldValue = Mage::registry($key);
Mage::register($key, $value, true);
$this->_replacedRegistry[$key] = $oldValue;
return $this;
}
/**
* Shortcut for expectation data object retrieval
* Can be called with arguments array or in usual method
*
* @param string|array $pathFormat
* @param mixed $arg1
* @param mixed $arg2 ...
* @return Varien_Object
*/
protected function expected($firstArgument = null)
{
if (!$this->getExpectation()->isLoaded()) {
$this->getExpectation()->loadByTestCase($this);
$this->getExpectation()->apply();
}
if (!is_array($firstArgument)) {
$arguments = func_get_args();
} else {
$arguments = $firstArgument;
}
return new Varien_Object($dataPart);
$pathFormat = null;
if ($arguments) {
$pathFormat = array_shift($arguments);
}
return $this->_expectations;
return $this->getExpectation()
->getDataObject($pathFormat, $arguments);
}
/**
* Retrieve mock builder for grouped class alias
*
* @param string $type block|model|helper
* @param string $classAlias
* @return PHPUnit_Framework_MockObject_MockBuilder
*/
public function getGroupedClassMockBuilder($type, $classAlias)
{
$className = Mage::getConfig()->getGroupedClassName($type, $classAlias);
return $this->getMockBuilder($className);
}
/**
* Retrieves a mock builder for a block class alias
*
* @param string $classAlias
* @return PHPUnit_Framework_MockObject_MockBuilder
*/
public function getBlockMockBuilder($classAlias)
{
return $this->getGroupedClassMockBuilder('block', $classAlias);
}
/**
* Retrieves a mock builder for a model class alias
*
* @param string $classAlias
* @return PHPUnit_Framework_MockObject_MockBuilder
*/
public function getModelMockBuilder($classAlias)
{
return $this->getGroupedClassMockBuilder('model', $classAlias);
}
/**
* Retrieves a mock builder for a helper class alias
*
* @param string $classAlias
* @return PHPUnit_Framework_MockObject_MockBuilder
*/
public function getHelperMockBuilder($classAlias)
{
return $this->getGroupedClassMockBuilder('helper', $classAlias);
}
/**
* Retrieves a mock object for the specified model class alias.
*
* @param string $classAlias
* @param array $methods
* @param boolean $isAbstract
* @param array $constructorArguments
* @param string $mockClassAlias
* @param boolean $callOriginalConstructor
* @param boolean $callOriginalClone
* @param boolean $callAutoload
* @return PHPUnit_Framework_MockObject_MockObject
*/
public function getModelMock($classAlias, $methods = array(), $isAbstract = false,
array $constructorArguments = array(),
$mockClassAlias = '', $callOriginalConstructor = true,
$callOriginalClone = true, $callAutoload = true)
{
return $this->getGroupedClassMock('model', $methods, $isAbstract,
$constructorArguments, $mockClassAlias,
$callOriginalConstructor, $callOriginalClone,
$callAutoload);
}
/**
* Retrieves a mock object for the specified helper class alias.
*
* @param string $classAlias
* @param array $methods
* @param boolean $isAbstract
* @param array $constructorArguments
* @param string $mockClassAlias
* @param boolean $callOriginalConstructor
* @param boolean $callOriginalClone
* @param boolean $callAutoload
* @return PHPUnit_Framework_MockObject_MockObject
*/
public function getHelperMock($classAlias, $methods = array(), $isAbstract = false,
array $constructorArguments = array(),
$mockClassAlias = '', $callOriginalConstructor = true,
$callOriginalClone = true, $callAutoload = true)
{
return $this->getGroupedClassMock('helper', $methods, $isAbstract,
$constructorArguments, $mockClassAlias,
$callOriginalConstructor, $callOriginalClone,
$callAutoload);
}
/**
* Retrieves a mock object for the specified helper class alias.
*
* @param string $classAlias
* @param array $methods
* @param boolean $isAbstract
* @param array $constructorArguments
* @param string $mockClassAlias
* @param boolean $callOriginalConstructor
* @param boolean $callOriginalClone
* @param boolean $callAutoload
* @return PHPUnit_Framework_MockObject_MockObject
*/
public function getBlockMock($classAlias, $methods = array(), $isAbstract = false,
array $constructorArguments = array(),
$mockClassAlias = '', $callOriginalConstructor = true,
$callOriginalClone = true, $callAutoload = true)
{
return $this->getGroupedClassMock('block', $methods, $isAbstract,
$constructorArguments, $mockClassAlias,
$callOriginalConstructor, $callOriginalClone,
$callAutoload);
}
/**
* Returns class name by grouped class alias
*
* @param string $type block/model/helper/resource_model
* @param string $classAlias
*/
protected function getGroupedClassName($type, $classAlias)
{
if ($type === 'resource_model') {
return Mage::getConfig()->getResourceModelClassName($classAlias);
}
return Mage::getConfig()->getGroupedClassName($type, $classAlias);
}
/**
* Retrieves a mock object for the specified grouped class alias.
*
* @param string $type
* @param string $classAlias
* @param array $methods
* @param boolean $isAbstract
* @param array $constructorArguments
* @param string $mockClassAlias
* @param boolean $callOriginalConstructor
* @param boolean $callOriginalClone
* @param boolean $callAutoload
* @return PHPUnit_Framework_MockObject_MockObject
*/
public function getGroupedClassMock($type, $classAlias, $methods = array(), $isAbstract = false,
array $constructorArguments = array(),
$mockClassAlias = '', $callOriginalConstructor = true,
$callOriginalClone = true, $callAutoload = true)
{
if (!empty($mockClassAlias)) {
} else {
$mockClassName = '';
}
$mockBuilder = $this->getGroupedClassMockBuilder($type, $classAlias);
if ($callOriginalConstructor === false) {
$mockBuilder->disableOriginalConstructor();
}
if ($callOriginalClone === false) {
$mockBuilder->disableOriginalClone();
}
if ($callAutoload === false) {
$mockBuilder->disableAutoload();
}
$mockBuilder->setMethods($methods);
$mockBuilder->setConstructorArgs($arguments);
$mockBuilder->setMockClassName($mockClassName);
if ($isAbstract) {
return $mockBuilder->getMockForAbstractClass();
}
return $mockBuilder->getMock();
}
/**
* Retrieves fixture model singleton
*
* @return EcomDev_PHPUnit_Model_Fixture
* @deprecated since 0.2.0 use getFixture() method instead
*/
protected function _getFixture()
{
return Mage::getSingleton('ecomdev_phpunit/fixture');
return $this->getFixture();
}
/**
* Retrieves fixture model singleton
*
* @return EcomDev_PHPUnit_Model_Fixture
*/
protected function getFixture()
{
return Mage::getSingleton($this->getLoadableClassAlias(
'fixture',
self::XML_PATH_DEFAULT_FIXTURE_MODEL
));;
}
/**
* Loads YAML file from directory inside of the unit test class
* Enter description here ...
* Returns expectation model singleton
*
* @return EcomDev_PHPUnit_Model_Expectation
*/
protected function getExpectation()
{
return Mage::getSingleton($this->getLoadableClassAlias(
'expectation',
self::XML_PATH_DEFAULT_EXPECTATION_MODEL
));
}
/**
* Retrieves loadable class alias from annotation or configuration node
* E.g. class alias for fixture model can be specified via @fixtureModel annotation
*
* @param string $type
* @param string $configPath
*/
protected function getLoadableClassAlias($type, $configPath)
{
$annotationValue = $this->getAnnotationByName($type .'Model' , 'class');
if (current($annotationValue)) {
$classAlias = current($annotationValue);
} else {
$classAlias = Mage::getConfig()->getNode($configPath);
}
return $classAlias;
}
/**
* Protected wrapper for _getYamlFilePath method. Backward campatibility.
*
* @see EcomDev_PHPUnit_Test_Case::getYamlFilePath()
*
* @param string $type type of YAML data (fixtures,expectations,dataproviders)
* @param string|null $name the file name for loading, if equals to null,
* the current test name will be used
* @return string|boolean
* @deprecated since 0.2.0
*/
protected function _getYamlFilePath($type, $name = null)
{
return $this->getYamlFilePath($type, $name);
}
/**
* Loads YAML file from directory inside of the unit test class
*
* @param string $type type of YAML data (fixtures,expectations,dataproviders)
* @param string|null $name the file name for loading, if equals to null,
* the current test name will be used
* @return string|boolean
*/
public function getYamlFilePath($type, $name = null)
{
if ($name === null) {
$name = $this->getName(false);
......@@ -161,24 +483,11 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
*/
protected function setUp()
{
$this->getFixture()->loadByTestCase($this);
$annotations = $this->getAnnotations();
if (isset($annotations['method']['loadFixture'])) {
foreach ($annotations['method']['loadFixture'] as $fixture) {
if (empty($fixture)) {
$fixture = null;
}
$filePath = $this->_getYamlFilePath('fixtures', $fixture);
if (!$filePath) {
throw new RuntimeException('Unable to load fixture for test');
}
$this->_getFixture()->loadYaml($filePath);
}
}
// Pass methods for
$this->_getFixture()->setOptions($annotations['method']);
$this->_getFixture()->apply();
$this->getFixture()->setOptions($annotations['method']);
$this->getFixture()->apply();
parent::setUp();
}
......@@ -186,12 +495,13 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
* Implements default data provider functionality,
* returns array data loaded from Yaml file with the same name as test method
*
* @param string $testName
* @return array
*/
public function dataProvider($testName)
{
$this->setName($testName);
$filePath = $this->_getYamlFilePath('providers');
$filePath = $this->getYamlFilePath('providers');
$this->setName(null);
if (!$filePath) {
......@@ -231,8 +541,19 @@ abstract class EcomDev_PHPUnit_Test_Case extends PHPUnit_Framework_TestCase
$this->_originalStore = null;
}
$this->_expectations = null; // Clear expectation values
$this->_getFixture()->discard(); // Clear applied fixture
if ($this->getExpectation()->isLoaded()) {
$this->getExpectation()->discard();
}
Mage::getConfig()->flushReplaceInstanceCreation();
Mage::app()->getLayout()->reset();
foreach ($this->_replacedRegistry as $registryPath => $originalValue) {
Mage::register($registryPath, $originalValue, true);
}
$this->getFixture()->discard(); // Clear applied fixture
parent::tearDown();
}
......
......@@ -51,9 +51,16 @@
<helpers>Helper</helpers>
<blocks>Block</blocks>
</groups>
<!-- Test suite that will be used for creation of each of the tests -->
<test_suite>EcomDev_PHPUnit_Test_Suite_Group</test_suite>
<layout>
<model>ecomdev_phpunit/layout</model>
</layout>
<expectation>
<!-- Default model for loading of expectations -->
<model>ecomdev_phpunit/expectation</model>
</expectation>
<fixture>
<!-- Default model for loading of fixtures -->
<model>ecomdev_phpunit/fixture</model>
<eav>
<!-- Here goes the list of fixture loaders for EAV
If no fixture loader is specified for entity, then default will be used
......
<?php
/**
* PHP Unit test suite for Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
*
* @category EcomDev
* @package EcomDev_PHPUnit
* @copyright Copyright (c) 2011 Ecommerce Developers (http://www.ecomdev.org)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
* @author Ivan Chepurnyi <ivan.chepurnyi@ecomdev.org>
*/
class EcomDev_Utils_Reflection
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment