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