We will work on Apr 26th (Saturday) and will be off from Apr 30th (Wednesday) until May 2nd (Friday) for public holiday in our country

Commit c8821f04 authored by Ivan Chepurnyi's avatar Ivan Chepurnyi

Refactor unit tests for db info retrieval

parent 02690886
...@@ -8,7 +8,6 @@ class EcomDev_PHPUnit_Model_Mysql4_Db_Info implements EcomDev_PHPUnit_Model_Mysq ...@@ -8,7 +8,6 @@ class EcomDev_PHPUnit_Model_Mysql4_Db_Info implements EcomDev_PHPUnit_Model_Mysq
/** @var array Information about the magento database [table => [...]]. */ /** @var array Information about the magento database [table => [...]]. */
protected $_information; protected $_information;
/** /**
* Before fetching information about a table. * Before fetching information about a table.
* *
...@@ -22,25 +21,30 @@ class EcomDev_PHPUnit_Model_Mysql4_Db_Info implements EcomDev_PHPUnit_Model_Mysq ...@@ -22,25 +21,30 @@ class EcomDev_PHPUnit_Model_Mysql4_Db_Info implements EcomDev_PHPUnit_Model_Mysq
// iterate over each available table // iterate over each available table
$listTables = $this->getAdapter()->listTables(); $listTables = $this->getAdapter()->listTables();
foreach ($listTables as $tableName) foreach ($listTables as $tableName) {
{
// describe the table // describe the table
$data = new Varien_Object(); $data = new Varien_Object();
$data->setData($this->getAdapter()->describeTable($tableName)); $columns = array();
foreach ($this->getAdapter()->describeTable($tableName) as $column => $info) {
$columns[$column]['type'] = $info['DATA_TYPE'];
$columns[$column]['length'] = $info['LENGTH'];
$columns[$column]['unsigned'] = (bool)$info['UNSIGNED'];
$columns[$column]['primary'] = (bool)$info['PRIMARY'];
$columns[$column]['default'] = $info['DEFAULT'];
}
$data->setColumns($columns);
$foreignKeys = $this->getAdapter()->getForeignKeys($tableName); $foreignKeys = $this->getAdapter()->getForeignKeys($tableName);
$dependency = array(); $dependency = array();
if (is_array($foreignKeys)) if (is_array($foreignKeys)) {
{
// add each depending table // add each depending table
foreach ($foreignKeys as $keyData) foreach ($foreignKeys as $keyData) {
{
$dependency[] = $keyData['REF_TABLE_NAME']; $dependency[] = $keyData['REF_TABLE_NAME'];
} }
} }
$data->setDependencies($dependency); $data->setDependencies($dependency);
$this->_information[$tableName] = $data; $this->_information[$tableName] = $data;
} }
...@@ -102,9 +106,8 @@ class EcomDev_PHPUnit_Model_Mysql4_Db_Info implements EcomDev_PHPUnit_Model_Mysq ...@@ -102,9 +106,8 @@ class EcomDev_PHPUnit_Model_Mysql4_Db_Info implements EcomDev_PHPUnit_Model_Mysq
*/ */
public function setAdapter($adapter) public function setAdapter($adapter)
{ {
if (!($adapter instanceof Zend_Db_Adapter_Abstract)) if (!($adapter instanceof Zend_Db_Adapter_Abstract)) {
{ throw new InvalidArgumentException('Adapter should be an instance of Zend_Db_Adapter_Abstract');
throw new InvalidArgumentException('Unsupported adapter ' . get_class($adapter));
} }
$this->_adapter = $adapter; $this->_adapter = $adapter;
......
<?php <?php
use EcomDev_Utils_Reflection as ReflectionUtil;
class EcomDev_PHPUnitTest_Test_Model_Mysql4_Db_InfoTest extends EcomDev_PHPUnit_Test_Case class EcomDev_PHPUnitTest_Test_Model_Mysql4_Db_InfoTest extends EcomDev_PHPUnit_Test_Case
{ {
/** @var EcomDev_PHPUnit_Model_Mysql4_Db_InfoInterface */ /** @var EcomDev_PHPUnit_Model_Mysql4_Db_Info */
protected $_factory; protected $_info;
/** @var Varien_Db_Adapter_Pdo_Mysql|PHPUnit_Framework_MockObject_MockObject */
protected $_adapter;
/** /**
...@@ -13,37 +18,58 @@ class EcomDev_PHPUnitTest_Test_Model_Mysql4_Db_InfoTest extends EcomDev_PHPUnit_ ...@@ -13,37 +18,58 @@ class EcomDev_PHPUnitTest_Test_Model_Mysql4_Db_InfoTest extends EcomDev_PHPUnit_
*/ */
public function setUp() public function setUp()
{ {
$this->_factory = new EcomDev_PHPUnit_Model_Mysql4_Db_Info(); $this->_info = new EcomDev_PHPUnit_Model_Mysql4_Db_Info();
$this->_adapter = $this->getMockBuilder('Varien_Db_Adapter_Pdo_Mysql')
->disableOriginalConstructor()
->getMock();
$this->_info->setAdapter($this->_adapter);
parent::setUp(); parent::setUp();
} }
/** /**
* Tear down unit testing. * Check if the model return the correct dependencies.
* *
* @return void * @dataProvider dataProvider
* @dataProviderFile tableStructure
*/ */
public function tearDown() public function testGetTheDependenciesForASpecificTable($tables)
{ {
$this->_factory = null; $this->_stubAdapter($tables);
parent::tearDown(); $this->assertEquals(array('mother'), $this->_info->getTableDependencies('child'));
$this->assertEquals(null, $this->_info->getTableDependencies('some_unknown'));
} }
/** /**
* Check if the model return the correct dependencies. * Stubs adapter method calls
* *
* @return void * @param array $tables
* @return $this
*/ */
public function testGetTheDependenciesForASpecificTable() protected function _stubAdapter($tables)
{ {
$this->_factory->setAdapter($this->_getMockedAdapter()); $this->_adapter->expects($this->any())
$this->_factory->fetch(); ->method('listTables')
->will($this->returnValue(array_keys($tables)));
$this->assertEquals(array('mother'), $this->_factory->getTableDependencies('child'));
$this->assertEquals(null, $this->_factory->getTableDependencies('some_unknown')); $columnsMap = array();
$foreignKeyMap = array();
foreach ($tables as $tableName => $info) {
$columnsMap[] = array($tableName, null, $info['columns']);
$foreignKeyMap[] = array($tableName, null, $info['foreign_keys']);
}
$this->_adapter->expects($this->any())
->method('describeTable')
->will($this->returnValueMap($columnsMap));
$this->_adapter->expects($this->any())
->method('getForeignKeys')
->will($this->returnValueMap($foreignKeyMap));
return $this;
} }
...@@ -54,42 +80,43 @@ class EcomDev_PHPUnitTest_Test_Model_Mysql4_Db_InfoTest extends EcomDev_PHPUnit_ ...@@ -54,42 +80,43 @@ class EcomDev_PHPUnitTest_Test_Model_Mysql4_Db_InfoTest extends EcomDev_PHPUnit_
*/ */
public function testItCanResetTheFetchedInformation() public function testItCanResetTheFetchedInformation()
{ {
// write something to the field via reflection ReflectionUtil::setRestrictedPropertyValue(
$reflect = $this->_getReflection(); $this->_info,
$property = $reflect->getProperty('_information'); '_information',
$property->setAccessible(true); array(uniqid())
$property->setValue($this->_factory, array(uniqid())); );
$this->_factory->reset(); $this->_info->reset();
$this->assertEmpty($property->getValue($this->_factory)); $this->assertAttributeSame(
null,
'_information',
$this->_info
);
} }
/** /**
* Check if the fetched information about a table is correct. * Check if the fetched information about a table is correct.
* *
* @param $tables
* @return void * @return void
* @dataProvider dataProvider
* @dataProviderFile tableStructure
* @loadExpectation fetchData
*/ */
public function testItFetchesInformationAboutATable() public function testItFetchesInformationAboutATable($tables)
{ {
$adapterMock = $this->_getMockedAdapter(); $this->_stubAdapter($tables);
$this->_info->fetch();
// check the fetched data
$this->_factory->setAdapter($adapterMock); $information = $this->readAttribute($this->_info, '_information');
$this->_factory->fetch(); $tables = $this->expected()->getTables();
$reflectObject = $this->_getReflection(); foreach ($tables as $tableName => $data) {
$property = $reflectObject->getProperty('_information'); $this->assertArrayHasKey($tableName, $information);
$property->setAccessible(true); $this->assertEquals($data, $information[$tableName]->getData());
$information = $property->getValue($this->_factory); }
$this->assertEquals(array_keys($information), $adapterMock->listTables());
/** @var Varien_Object $child */
$child = $information['child'];
$this->assertNotNull($child->getDependencies());
$this->assertEquals(array('mother'), $child->getDependencies());
} }
...@@ -97,128 +124,29 @@ class EcomDev_PHPUnitTest_Test_Model_Mysql4_Db_InfoTest extends EcomDev_PHPUnit_ ...@@ -97,128 +124,29 @@ class EcomDev_PHPUnitTest_Test_Model_Mysql4_Db_InfoTest extends EcomDev_PHPUnit_
* Check whether an adapter can be set and get. * Check whether an adapter can be set and get.
* *
* @return null * @return null
* @expectedException InvalidArgumentException
* @expectedExceptionMessage Adapter should be an instance of Zend_Db_Adapter_Abstract
*/ */
public function testYouNeedToProvideAnAdapter() public function testYouNeedToProvideAnAdapter()
{ {
/** @var Varien_Db_Adapter_Interface $adapterMock */ $this->_info->setAdapter(null);
$adapterMock = $this->getMock('Varien_Db_Adapter_Pdo_Mysql', array(), array(), '', false);
$this->assertTrue($adapterMock instanceof Varien_Db_Adapter_Pdo_Mysql);
$this->_factory->setAdapter($adapterMock);
$this->assertSame($adapterMock, $this->_factory->getAdapter());
return null;
} }
/** /**
* Mock the adapter without any configuration. * Tests that setters and getters for adapter are working correctly
* *
* @return Varien_Db_Adapter_Pdo_Mysql|PHPUnit_Framework_MockObject_MockObject
*/ */
protected function _getMockedAdapter() public function testItSetsAnAdapter()
{ {
/** @var Varien_Db_Adapter_Pdo_Mysql|PHPUnit_Framework_MockObject_MockObject $adapterMock Mock without connecting to a server. */ ReflectionUtil::setRestrictedPropertyValue(
$adapterMock = $this->getMock( $this->_info,
'Varien_Db_Adapter_Pdo_Mysql', '_adapter',
array( null
'listTables',
'describeTable',
'getForeignKeys',
),
array(),
'',
false // ignore original constructor
); );
$this->assertTrue($adapterMock instanceof Varien_Db_Adapter_Pdo_Mysql); $this->_info->setAdapter($this->_adapter);
$this->assertSame($this->_adapter, $this->_info->getAdapter());
// mock listTables: with two tables that depend on each other
$listTablesReturn = array('child', 'mother');
$adapterMock->expects($this->any())
->method('listTables')
->will(
$this->returnValue($listTablesReturn)
);
$this->assertEquals($adapterMock->listTables(), $listTablesReturn);
// mock describeTable
$describeTableReturn = array(
array(
'SCHEMA_NAME' => 'test',
'TABLE_NAME' => 'foo',
'COLUMN_NAME' => 'bar',
'COLUMN_POSITION' => '0',
'DATA_TYPE' => 'int',
'DEFAULT' => '',
'NULLABLE' => '',
'LENGTH' => '',
'SCALE' => '',
'UNSIGNED' => true,
'PRIMARY' => false,
'PRIMARY_POSITION' => null,
'IDENTITY' => false,
),
);
$adapterMock->expects($this->any())
->method('describeTable')
->will(
$this->returnValue($describeTableReturn)
);
$this->assertEquals($adapterMock->describeTable('child'), $describeTableReturn);
// mock adapter::getForeignKeys
$getForeignKeysReturn = array(
'child' => array(
'fk_mother' => array(
'FK_NAME' => 'idMother',
'SCHEMA_NAME' => 'test',
'TABLE_NAME' => 'child',
'COLUMN_NAME' => 'kf_mother',
'REF_SHEMA_NAME' => 'test',
'REF_TABLE_NAME' => 'mother',
'REF_COLUMN_NAME' => 'idMother',
'ON_DELETE' => '',
'ON_UPDATE' => ''
),
),
'mother' => array(),
);
$adapterMock->expects($this->any())
->method('getForeignKeys')
->will(
$this->returnCallback(
function ($tableName) use ($getForeignKeysReturn)
{
return $getForeignKeysReturn[$tableName];
}
)
);
$this->assertEquals($adapterMock->getForeignKeys('child'), $getForeignKeysReturn['child']);
$this->assertEquals(
$adapterMock->getForeignKeys('mother'),
$getForeignKeysReturn['mother']
);
return $adapterMock;
} }
/**
* Reflect the object.
*
* @return ReflectionObject
*/
protected function _getReflection()
{
$reflect = new ReflectionObject($this->_factory);
return $reflect;
}
} }
-
- child:
columns:
child_id:
SCHEMA_NAME: test
TABLE_NAME: child
COLUMN_NAME: child_id
COLUMN_POSITION: 0
DATA_TYPE: int
DEFAULT: ''
LENGTH: 10
UNSIGNED: true
PRIMARY: true
PRIMARY_POSITION: 0
IDENTITY: true
parent_id:
SCHEMA_NAME: test
TABLE_NAME: child
COLUMN_NAME: parent_id
COLUMN_POSITION: 0
DATA_TYPE: int
DEFAULT: ''
LENGTH: 10
UNSIGNED: true
PRIMARY: false
PRIMARY_POSITION: 0
IDENTITY: false
foreign_keys:
fk_mother:
FK_NAME: fk_mother
SCHEMA_NAME: test
TABLE_NAME: child
COLUMN_NAME: parent_id
REF_SHEMA_NAME: test
REF_TABLE_NAME: mother
REF_COLUMN_NAME: mother_id
ON_DELETE: ''
ON_UPDATE: ''
mother:
columns:
mother_id:
SCHEMA_NAME: test
TABLE_NAME: mother
COLUMN_NAME: mother_id
COLUMN_POSITION: 0
DATA_TYPE: int
DEFAULT: ''
LENGTH: 10
UNSIGNED: true
PRIMARY: true
PRIMARY_POSITION: 0
IDENTITY: true
name:
SCHEMA_NAME: test
TABLE_NAME: mother
COLUMN_NAME: name
COLUMN_POSITION: 0
DATA_TYPE: varchar
DEFAULT: ''
LENGTH: 255
UNSIGNED: false
PRIMARY: false
PRIMARY_POSITION: 0
IDENTITY: false
foreign_keys: [ ]
\ No newline at end of file
tables:
mother:
columns:
mother_id:
type: int
length: 10
unsigned: true
primary: true
default: ''
name:
type: varchar
length: 255
unsigned: false
primary: false
default: ''
dependencies: []
child:
columns:
child_id:
type: int
length: 10
unsigned: true
primary: true
default: ''
parent_id:
type: int
length: 10
unsigned: true
primary: false
default: ''
dependencies:
- mother
\ No newline at end of file
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