39     private $objectManagerHelper;
    44     private $elementFactoryMock;
    49     private $dbSchemaReaderMock;
    54     private $shardingMock;
    58         $this->elementFactoryMock = $this->getMockBuilder(ElementFactory::class)
    59             ->disableOriginalConstructor()
    61         $this->dbSchemaReaderMock = $this->getMockBuilder(DbSchemaReaderInterface::class)
    62             ->getMockForAbstractClass();
    63         $this->shardingMock = $this->getMockBuilder(Sharding::class)
    64             ->disableOriginalConstructor()
    67         $this->objectManagerHelper = 
new ObjectManagerHelper($this);
    68         $this->model = $this->objectManagerHelper->getObject(
    69             \
Magento\Framework\Setup\Declaration\
Schema\Db\SchemaBuilder::class,
    71                 'elementFactory' => $this->elementFactoryMock,
    72                 'dbSchemaReader' => $this->dbSchemaReaderMock,
    73                 'sharding' => $this->shardingMock
    89                             'name' => 
'first_column',
    96                             'name' => 
'foreign_column',
   102                             'name' => 
'second_column',
   103                             'type' => 
'timestamp',
   104                             'default' => 
'CURRENT_TIMESTAMP',
   110                             'name' => 
'ref_column',
   119                         'some_foreign_key' => [
   120                             'name' => 
'some_foreign_key',
   122                             'column' => 
'foreign_column',
   123                             'table' => 
'first_table',
   124                             'referenceTable' => 
'second_table',
   125                             'referenceColumn' => 
'ref_column'   137                             'nameWithoutPrefix' => 
'PRIMARY',
   144                             'name' => 
'FIRST_INDEX',
   145                             'nameWithoutPrefix' => 
'FIRST_INDEX',
   162     private function createTable(
$name)
   260         return new Timestamp(
   277     public function testBuild(array 
$columns, array $references, array $constraints, array $indexes)
   279         $this->prepareSchemaMocks(
$columns, $references, $constraints, $indexes);
   280         $resourceConnectionMock = $this->getMockBuilder(ResourceConnection::class)
   281             ->disableOriginalConstructor()
   283         $resourceConnectionMock->expects(self::any())
   284             ->method(
'getTableName')
   285             ->willReturnArgument(0);
   287         $schema = $this->objectManagerHelper->getObject(
   289             [
'resourceConnection' => $resourceConnectionMock]
   303     public function testBuildUnknownIndexColumn(array 
$columns, array $references, array $constraints, array $indexes)
   305         $indexes[
'second_table'][
'FIRST_INDEX'][
'column'][] = 
'unknown_column';
   306         $this->prepareSchemaMocks(
$columns, $references, $constraints, $indexes);
   307         $resourceConnectionMock = $this->getMockBuilder(ResourceConnection::class)
   308             ->disableOriginalConstructor()
   311         $schema = $this->objectManagerHelper->getObject(
   313             [
'resourceConnection' => $resourceConnectionMock]
   315         $this->expectException(\Exception::class);
   316         $this->expectExceptionMessage(
   317             'User Warning: Column unknown_column does not exist for index/constraint FIRST_INDEX in table second_table.'   331     private function prepareSchemaMocks(array 
$columns, array $references, array $constraints, array $indexes)
   333         $withContext = [[
'first_table', 
'default'], [
'second_table', 
'default']];
   334         $this->shardingMock->expects(self::once())
   335             ->method(
'getResources')
   336             ->willReturn([
'default']);
   337         $this->dbSchemaReaderMock->expects(self::once())
   338             ->method(
'readTables')
   340             ->willReturn([
'first_table', 
'second_table']);
   341         $this->dbSchemaReaderMock->expects($this->any())
   342             ->method(
'getTableOptions')
   343             ->withConsecutive(...array_values($withContext))
   344             ->willReturnOnConsecutiveCalls(
   345                 [
'engine' => 
'innodb', 
'comment' => 
'', 
'charset' => 
'utf-8', 
'collation' => 
'utf-8'],
   346                 [
'engine' => 
'innodb', 
'comment' => 
'Not null comment', 
'charset' => 
'utf-8', 
'collation' => 
'utf-8']
   348         $this->dbSchemaReaderMock->expects($this->any())
   349             ->method(
'readColumns')
   350             ->withConsecutive(...array_values($withContext))
   351             ->willReturnOnConsecutiveCalls(
$columns[
'first_table'], 
$columns[
'second_table']);
   352         $this->dbSchemaReaderMock->expects($this->any())
   353             ->method(
'readIndexes')
   354             ->withConsecutive(...array_values($withContext))
   355             ->willReturnOnConsecutiveCalls([], $indexes[
'second_table']);
   356         $this->dbSchemaReaderMock->expects($this->any())
   357             ->method(
'readConstraints')
   358             ->withConsecutive(...array_values($withContext))
   359             ->willReturnOnConsecutiveCalls($constraints[
'first_table'], []);
   360         $this->dbSchemaReaderMock->expects($this->any())
   361             ->method(
'readReferences')
   362             ->withConsecutive(...array_values($withContext))
   363             ->willReturnOnConsecutiveCalls($references[
'first_table'], []);
   364         $table = $this->createTable(
'first_table');
   365         $refTable = $this->createTable(
'second_table');
   366         $refColumn = $this->createIntegerColumn(
'ref_column', $refTable);
   367         $index = $this->createIndex(
'FIRST_INDEX', 
$table, [$refColumn]);
   368         $refTable->addColumns([$refColumn]);
   369         $refTable->addIndexes([
$index]);
   370         $firstColumn = $this->createIntegerAIColumn(
'first_column', 
$table);
   371         $foreignColumn = $this->createIntegerColumn(
'foreign_column', 
$table);
   372         $timestampColumn = $this->createTimestampColumn(
'second_column', 
$table);
   373         $primaryKey = $this->createPrimaryConstraint(
$table, [$firstColumn]);
   374         $foreignKey = 
new Reference(
   384         $table->addColumns([$firstColumn, $foreignColumn, $timestampColumn]);
   385         $table->addConstraints([$foreignKey, $primaryKey]);
   386         $this->elementFactoryMock->expects($this->any())
   392                         'name' =>
'first_table',
   393                         'resource' => 
'default',
   394                         'engine' => 
'innodb',
   396                         'charset' => 
'utf-8',
   397                         'collation' => 
'utf-8'   403                         'name' => 
'first_column',
   414                         'name' => 
'foreign_column',
   424                         'name' => 
'second_column',
   425                         'type' => 
'timestamp',
   427                         'default' => 
'CURRENT_TIMESTAMP',
   436                         'columns' => [$firstColumn],
   438                         'nameWithoutPrefix' => 
'PRIMARY',
   439                         'column' => [
'first_column'],
   445                         'name' =>
'second_table',
   446                         'resource' => 
'default',
   447                         'engine' => 
'innodb',
   448                         'comment' => 
'Not null comment',
   449                         'charset' => 
'utf-8',
   450                         'collation' => 
'utf-8'   456                         'name' => 
'ref_column',
   458                         'table' => $refTable,
   466                         'name' => 
'FIRST_INDEX',
   467                         'table' => $refTable,
   468                         'column' => [
'ref_column'],
   469                         'columns' => [$refColumn],
   470                         'nameWithoutPrefix' => 
'FIRST_INDEX',
   476                         'name' => 
'some_foreign_key',
   478                         'column' => $foreignColumn,
   480                         'referenceTable' => $refTable,
   481                         'referenceColumn' => $refColumn,
   485             ->willReturnOnConsecutiveCalls(
 
if(!isset($_GET['name'])) $name