[TASK] Use constructor injection in DataMapper 79/59279/6
authorAlexander Schnitzler <git@alexanderschnitzler.de>
Sat, 22 Dec 2018 16:05:19 +0000 (17:05 +0100)
committerAnja Leichsenring <aleichsenring@ab-softlab.de>
Fri, 11 Jan 2019 15:20:11 +0000 (16:20 +0100)
Class DataMapper does no longer use setter injection but
constructor injection instead.

Releases: master
Resolves: #87305
Change-Id: I88596a5e2e22deb8d11f6d83901c2c660b81bf0c
Reviewed-on: https://review.typo3.org/59279
Tested-by: TYPO3com <noreply@typo3.com>
Reviewed-by: Mona Muzaffar <mona.muzaffar@gmx.de>
Tested-by: Mona Muzaffar <mona.muzaffar@gmx.de>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
typo3/sysext/core/Documentation/Changelog/master/Breaking-87305-UseConstructorInjectionInDataMapper.rst [new file with mode: 0644]
typo3/sysext/core/Documentation/Changelog/master/Deprecation-87305-UseConstructorInjectionInDataMapper.rst [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/Generic/Mapper/DataMapper.php
typo3/sysext/extbase/Classes/Persistence/Generic/QueryResult.php
typo3/sysext/extbase/Tests/Unit/Persistence/Generic/Mapper/DataMapperTest.php
typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php

diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-87305-UseConstructorInjectionInDataMapper.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-87305-UseConstructorInjectionInDataMapper.rst
new file mode 100644 (file)
index 0000000..57f3cef
--- /dev/null
@@ -0,0 +1,51 @@
+.. include:: ../../Includes.txt
+
+==========================================================
+Breaking: #87305 - Use constructor injection in DataMapper
+==========================================================
+
+See :issue:`87305`
+
+Description
+===========
+
+Class :php:`\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper` does no longer use setter injection. Instead, constructor injection is used.
+
+
+Impact
+======
+
+The method signature of the constructor changed. This means:
+- The amount of constructor arguments increased
+- The order of arguments possibly changed
+
+
+Affected Installations
+======================
+
+All installations that create instances of the class :php:`\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper` using :php:`GeneralUtility::makeInstance` or :php:`ObjectManager->get`.
+
+
+Migration
+=========
+
+If possible, do not create instances yourself. Avoid :php:`GeneralUtility::makeInstance` and :php:`ObjectManager->get`. Instead use dependency injection, preferably constructor injection:
+
+.. code-block:: php
+
+       public function __constructor(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper $object)
+       {
+           $this->property = $object;
+       }
+
+If dependency injection is not possible, check the dependencies and instantiate objects via the object manager:
+
+.. code-block:: php
+
+       $object = $objectManager->get(
+           \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper::class,
+           $objectManager->get(\TYPO3\CMS\Extbase\Reflection\ReflectionService::class),
+           // ...
+       );
+
+.. index:: PHP-API, FullyScanned, ext:extbase
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-87305-UseConstructorInjectionInDataMapper.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-87305-UseConstructorInjectionInDataMapper.rst
new file mode 100644 (file)
index 0000000..f989901
--- /dev/null
@@ -0,0 +1,32 @@
+.. include:: ../../Includes.txt
+
+=============================================================
+Deprecation: #87305 - Use constructor injection in DataMapper
+=============================================================
+
+See :issue:`87305`
+
+Description
+===========
+
+The 8th argument (:php:`\TYPO3\CMS\Extbase\Persistence\QueryInterface`) of method :php:`\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper->__construct` has been marked deprecated.
+
+
+Impact
+======
+
+Instantiating objects along with that argument will trigger a deprecation warning.
+
+
+Affected Installations
+======================
+
+All installations that create instances of the class :php:`\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper` while providing the 8th argument.
+
+
+Migration
+=========
+
+Instantiate the object without the 8th argument and use :php:`\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper->setQuery` if needed.
+
+.. index:: PHP-API, FullyScanned, ext:extbase
index 792cd8b..fd2d22c 100644 (file)
@@ -77,67 +77,49 @@ class DataMapper
 
     /**
      * DataMapper constructor.
-     * @param ?QueryInterface $query
-     */
-    public function __construct(?QueryInterface $query = null)
-    {
-        $this->query = $query;
-    }
-
-    /**
      * @param \TYPO3\CMS\Extbase\Reflection\ReflectionService $reflectionService
-     */
-    public function injectReflectionService(\TYPO3\CMS\Extbase\Reflection\ReflectionService $reflectionService)
-    {
-        $this->reflectionService = $reflectionService;
-    }
-
-    /**
      * @param \TYPO3\CMS\Extbase\Persistence\Generic\Qom\QueryObjectModelFactory $qomFactory
-     */
-    public function injectQomFactory(\TYPO3\CMS\Extbase\Persistence\Generic\Qom\QueryObjectModelFactory $qomFactory)
-    {
-        $this->qomFactory = $qomFactory;
-    }
-
-    /**
      * @param \TYPO3\CMS\Extbase\Persistence\Generic\Session $persistenceSession
-     */
-    public function injectPersistenceSession(\TYPO3\CMS\Extbase\Persistence\Generic\Session $persistenceSession)
-    {
-        $this->persistenceSession = $persistenceSession;
-    }
-
-    /**
      * @param \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory $dataMapFactory
-     */
-    public function injectDataMapFactory(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory $dataMapFactory)
-    {
-        $this->dataMapFactory = $dataMapFactory;
-    }
-
-    /**
      * @param \TYPO3\CMS\Extbase\Persistence\Generic\QueryFactoryInterface $queryFactory
-     */
-    public function injectQueryFactory(\TYPO3\CMS\Extbase\Persistence\Generic\QueryFactoryInterface $queryFactory)
-    {
-        $this->queryFactory = $queryFactory;
-    }
-
-    /**
      * @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
-     */
-    public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager)
-    {
+     * @param \TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher
+     * @param QueryInterface|null $query
+     */
+    public function __construct(
+        \TYPO3\CMS\Extbase\Reflection\ReflectionService $reflectionService,
+        \TYPO3\CMS\Extbase\Persistence\Generic\Qom\QueryObjectModelFactory $qomFactory,
+        \TYPO3\CMS\Extbase\Persistence\Generic\Session $persistenceSession,
+        \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory $dataMapFactory,
+        \TYPO3\CMS\Extbase\Persistence\Generic\QueryFactoryInterface $queryFactory,
+        \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager,
+        \TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher,
+        ?QueryInterface $query = null
+    ) {
+        $this->query = $query;
+        $this->reflectionService = $reflectionService;
+        $this->qomFactory = $qomFactory;
+        $this->persistenceSession = $persistenceSession;
+        $this->dataMapFactory = $dataMapFactory;
+        $this->queryFactory = $queryFactory;
         $this->objectManager = $objectManager;
+        $this->signalSlotDispatcher = $signalSlotDispatcher;
+
+        if ($query !== null) {
+            trigger_error(
+                'Constructor argument $query will be removed in TYPO3 v11.0, use setQuery method instead.',
+                E_USER_DEPRECATED
+            );
+            $this->query = $query;
+        }
     }
 
     /**
-     * @param \TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher
+     * @param QueryInterface $query
      */
-    public function injectSignalSlotDispatcher(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher)
+    public function setQuery(QueryInterface $query): void
     {
-        $this->signalSlotDispatcher = $signalSlotDispatcher;
+        $this->query = $query;
     }
 
     /**
index 94ddf9b..2303568 100644 (file)
@@ -84,7 +84,8 @@ class QueryResult implements QueryResultInterface
      */
     public function initializeObject()
     {
-        $this->dataMapper = $this->objectManager->get(DataMapper::class, $this->query);
+        $this->dataMapper = $this->objectManager->get(DataMapper::class);
+        $this->dataMapper->setQuery($this->query);
     }
 
     /**
index 87cb6d7..6464742 100644 (file)
@@ -29,22 +29,42 @@ use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
 class DataMapperTest extends UnitTestCase
 {
     /**
+     * This test does not actually test anything rather than map calls both mocked methods getTargetType and mapSingleRow
+     * while completely ignoring the result of the method.
+     * @todo: Cover this functionality by a functional test
+     *
      * @test
      */
     public function mapMapsArrayToObjectByCallingmapToObject()
     {
         $rows = [['uid' => '1234']];
         $object = new \stdClass();
+
         /** @var DataMapper|AccessibleObjectInterface|\PHPUnit_Framework_MockObject_MockObject $dataMapper */
-        $dataMapper = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper::class, ['mapSingleRow', 'getTargetType']);
+        $dataMapper = $this->getMockBuilder(DataMapper::class)
+            ->setConstructorArgs([
+                $this->createMock(\TYPO3\CMS\Extbase\Reflection\ReflectionService::class),
+                $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\Qom\QueryObjectModelFactory::class),
+                $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\Session::class),
+                $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class),
+                $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\QueryFactoryInterface::class),
+                $this->createMock(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface::class),
+                $this->createMock(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher::class),
+            ])
+            ->setMethods(['mapSingleRow', 'getTargetType'])
+            ->getMock();
+
         $dataMapper->expects($this->any())->method('getTargetType')->will($this->returnArgument(1));
-        $dataMapFactory = $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class);
-        $dataMapper->_set('dataMapFactory', $dataMapFactory);
         $dataMapper->expects($this->once())->method('mapSingleRow')->with($rows[0])->will($this->returnValue($object));
+
         $dataMapper->map(get_class($object), $rows);
     }
 
     /**
+     * This test does not actually test anything rather than mapSingleRow delegates functionality to
+     * the persistence session which is a mock itself.
+     * @todo: Cover this functionality by a functional test
+     *
      * @test
      */
     public function mapSingleRowReturnsObjectFromPersistenceSessionIfAvailable()
@@ -54,12 +74,29 @@ class DataMapperTest extends UnitTestCase
         $persistenceSession = $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\Session::class);
         $persistenceSession->expects($this->once())->method('hasIdentifier')->with('1234')->will($this->returnValue(true));
         $persistenceSession->expects($this->once())->method('getObjectByIdentifier')->with('1234')->will($this->returnValue($object));
-        $dataMapper = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper::class, ['dummy']);
-        $dataMapper->_set('persistenceSession', $persistenceSession);
+
+        $dataMapper = $this->getAccessibleMock(
+            DataMapper::class,
+            ['dummy'],
+            [
+                $this->createMock(\TYPO3\CMS\Extbase\Reflection\ReflectionService::class),
+                $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\Qom\QueryObjectModelFactory::class),
+                $persistenceSession,
+                $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class),
+                $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\QueryFactoryInterface::class),
+                $this->createMock(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface::class),
+                $this->createMock(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher::class),
+            ]
+        );
+
         $dataMapper->_call('mapSingleRow', get_class($object), $row);
     }
 
     /**
+     * This test has a far too complex setup to test a single unit. This actually is a functional test, accomplished
+     * by mocking the whole dependency chain. This test only tests code structure while it should test functionality.
+     * @todo: Cover this functionality by a functional test
+     *
      * @test
      */
     public function thawPropertiesSetsPropertyValues()
@@ -91,12 +128,23 @@ class DataMapperTest extends UnitTestCase
             ->setMethods(['getClassSchema'])
             ->getMock();
         $mockReflectionService->expects($this->any())->method('getClassSchema')->will($this->returnValue($classSchema));
-        $dataMapFactory = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class, ['dummy']);
+        $dataMapFactory = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class, ['dummy'], [], '', false);
         $dataMapFactory->_set('dataMaps', $dataMaps);
-        $dataMapper = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper::class, ['dummy']);
-        $dataMapper->_set('reflectionService', $mockReflectionService);
-        $dataMapper->_set('dataMapFactory', $dataMapFactory);
+        $dataMapper = $this->getAccessibleMock(
+            DataMapper::class,
+            ['dummy'],
+            [
+                $mockReflectionService,
+                $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\Qom\QueryObjectModelFactory::class),
+                $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\Session::class),
+                $dataMapFactory,
+                $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\QueryFactoryInterface::class),
+                $this->createMock(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface::class),
+                $this->createMock(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher::class),
+            ]
+        );
         $dataMapper->_call('thawProperties', $object, $row);
+
         $this->assertAttributeEquals('firstValue', 'firstProperty', $object);
         $this->assertAttributeEquals(1234, 'secondProperty', $object);
         $this->assertAttributeEquals(1.234, 'thirdProperty', $object);
@@ -106,6 +154,9 @@ class DataMapperTest extends UnitTestCase
     /**
      * Test if fetchRelatedEager method returns NULL when $fieldValue = '' and relation type == RELATION_HAS_ONE
      *
+     * This is a actually a functional test as it tests multiple units along with a very specific setup of dependencies.
+     * @todo: Cover this functionality by a functional test
+     *
      * @test
      */
     public function fetchRelatedEagerReturnsNullForEmptyRelationHasOne()
@@ -117,7 +168,7 @@ class DataMapperTest extends UnitTestCase
             ->disableOriginalConstructor()
             ->getMock();
         $dataMap->expects($this->any())->method('getColumnMap')->will($this->returnValue($columnMap));
-        $dataMapper = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper::class, ['getDataMap']);
+        $dataMapper = $this->getAccessibleMock(DataMapper::class, ['getDataMap'], [], '', false);
         $dataMapper->expects($this->any())->method('getDataMap')->will($this->returnValue($dataMap));
         $result = $dataMapper->_call('fetchRelatedEager', $this->createMock(\TYPO3\CMS\Extbase\DomainObject\AbstractEntity::class), 'SomeName', '');
         $this->assertEquals(null, $result);
@@ -126,6 +177,9 @@ class DataMapperTest extends UnitTestCase
     /**
      * Test if fetchRelatedEager method returns empty array when $fieldValue = '' and relation type != RELATION_HAS_ONE
      *
+     * This is a actually a functional test as it tests multiple units along with a very specific setup of dependencies.
+     * @todo: Cover this functionality by a functional test
+     *
      * @test
      */
     public function fetchRelatedEagerReturnsEmptyArrayForEmptyRelationNotHasOne()
@@ -137,7 +191,7 @@ class DataMapperTest extends UnitTestCase
             ->disableOriginalConstructor()
             ->getMock();
         $dataMap->expects($this->any())->method('getColumnMap')->will($this->returnValue($columnMap));
-        $dataMapper = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper::class, ['getDataMap']);
+        $dataMapper = $this->getAccessibleMock(DataMapper::class, ['getDataMap'], [], '', false);
         $dataMapper->expects($this->any())->method('getDataMap')->will($this->returnValue($dataMap));
         $result = $dataMapper->_call('fetchRelatedEager', $this->createMock(\TYPO3\CMS\Extbase\DomainObject\AbstractEntity::class), 'SomeName', '');
         $this->assertEquals([], $result);
@@ -147,9 +201,12 @@ class DataMapperTest extends UnitTestCase
      * Test if fetchRelatedEager method returns NULL when $fieldValue = ''
      * and relation type == RELATION_HAS_ONE without calling fetchRelated
      *
+     * This is a actually a functional test as it tests multiple units along with a very specific setup of dependencies.
+     * @todo: Cover this functionality by a functional test
+     *
      * @test
      */
-    public function mapObjectToClassPropertyReturnsNullForEmptyRelationHasOne()
+    public function MapObjectToClassPropertyReturnsNullForEmptyRelationHasOne()
     {
         $columnMap = new ColumnMap('columnName', 'propertyName');
         $columnMap->setTypeOfRelation(ColumnMap::RELATION_HAS_ONE);
@@ -158,7 +215,7 @@ class DataMapperTest extends UnitTestCase
             ->disableOriginalConstructor()
             ->getMock();
         $dataMap->expects($this->any())->method('getColumnMap')->will($this->returnValue($columnMap));
-        $dataMapper = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper::class, ['getDataMap', 'fetchRelated']);
+        $dataMapper = $this->getAccessibleMock(DataMapper::class, ['getDataMap', 'fetchRelated'], [], '', false);
         $dataMapper->expects($this->any())->method('getDataMap')->will($this->returnValue($dataMap));
         $dataMapper->expects($this->never())->method('fetchRelated');
         $result = $dataMapper->_call('mapObjectToClassProperty', $this->createMock(\TYPO3\CMS\Extbase\DomainObject\AbstractEntity::class), 'SomeName', '');
@@ -170,6 +227,9 @@ class DataMapperTest extends UnitTestCase
      * that are already registered in the persistence session
      * without query it from the persistence layer
      *
+     * This is a actually a functional test as it tests multiple units along with a very specific setup of dependencies.
+     * @todo: Cover this functionality by a functional test
+     *
      * @test
      */
     public function mapObjectToClassPropertyReturnsExistingObjectWithoutCallingFetchRelated()
@@ -198,9 +258,20 @@ class DataMapperTest extends UnitTestCase
         $mockReflectionService->expects($this->any())->method('getClassSchema')->will($this->returnValue($classSchema1));
 
         $dataMap->expects($this->any())->method('getColumnMap')->will($this->returnValue($columnMap));
-        $dataMapper = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper::class, ['getDataMap', 'getNonEmptyRelationValue']);
-        $dataMapper->_set('reflectionService', $mockReflectionService);
-        $dataMapper->_set('persistenceSession', $session);
+
+        $dataMapper = $this->getAccessibleMock(
+            DataMapper::class,
+            ['getDataMap', 'getNonEmptyRelationValue'],
+            [
+                $mockReflectionService,
+                $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\Qom\QueryObjectModelFactory::class),
+                $session,
+                $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory::class),
+                $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\QueryFactoryInterface::class),
+                $this->createMock(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface::class),
+                $this->createMock(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher::class),
+            ]
+        );
         $dataMapper->expects($this->any())->method('getDataMap')->will($this->returnValue($dataMap));
         $dataMapper->expects($this->never())->method('getNonEmptyRelationValue');
         $result = $dataMapper->_call('mapObjectToClassProperty', $object, 'relationProperty', $identifier);
@@ -236,10 +307,8 @@ class DataMapperTest extends UnitTestCase
      */
     public function mapDateTimeHandlesDifferentFieldEvaluations($value, $storageFormat, $expectedValue)
     {
-        $accessibleClassName = $this->buildAccessibleProxy(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper::class);
-
         /** @var DataMapper|AccessibleObjectInterface|\PHPUnit_Framework_MockObject_MockObject $accessibleDataMapFactory */
-        $accessibleDataMapFactory = new $accessibleClassName();
+        $accessibleDataMapFactory = $this->getAccessibleMock(DataMapper::class, ['dummy'], [], '', false);
 
         /** @var $dateTime NULL|\DateTime */
         $dateTime = $accessibleDataMapFactory->_callRef('mapDateTime', $value, $storageFormat);
@@ -254,12 +323,10 @@ class DataMapperTest extends UnitTestCase
     /**
      * @test
      */
-    public function mapDateTimeHandlesSubclassesOfDateTime()
+    public function testMapDateTimeHandlesSubclassesOfDateTime()
     {
-        $accessibleClassName = $this->buildAccessibleProxy(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper::class);
-
         /** @var DataMapper|AccessibleObjectInterface|\PHPUnit_Framework_MockObject_MockObject $accessibleDataMapFactory */
-        $accessibleDataMapFactory = new $accessibleClassName();
+        $accessibleDataMapFactory = $this->getAccessibleMock(DataMapper::class, ['dummy'], [], '', false);
         $targetType = 'TYPO3\CMS\Extbase\Tests\Unit\Persistence\Fixture\Model\CustomDateTime';
         $date = '2013-01-01 01:02:03';
         $storageFormat = 'datetime';
@@ -275,7 +342,9 @@ class DataMapperTest extends UnitTestCase
      */
     public function getPlainValueReturnsCorrectDateTimeFormat()
     {
-        $subject = new DataMapper();
+        /** @var DataMapper $subject */
+        $subject = $this->createPartialMock(DataMapper::class, ['dummy']);
+
         $columnMap = new ColumnMap('column_name', 'propertyName');
         $columnMap->setDateTimeStorageFormat('datetime');
         $datetimeAsString = '2013-04-15 09:30:00';
@@ -291,7 +360,9 @@ class DataMapperTest extends UnitTestCase
      */
     public function getPlainValueReturnsExpectedValues($expectedValue, $input)
     {
-        $dataMapper = new DataMapper();
+        /** @var DataMapper $dataMapper */
+        $dataMapper = $this->createPartialMock(DataMapper::class, ['dummy']);
+
         $this->assertSame($expectedValue, $dataMapper->getPlainValue($input));
     }
 
@@ -326,7 +397,9 @@ class DataMapperTest extends UnitTestCase
     {
         $this->expectException(UnexpectedTypeException::class);
         $this->expectExceptionCode(1274799934);
-        $dataMapper = new DataMapper();
+
+        /** @var DataMapper $dataMapper */
+        $dataMapper = $this->createPartialMock(DataMapper::class, ['dummy']);
         $input = $this->createMock(\TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy::class);
         $input->expects($this->once())->method('_loadRealInstance')->will($this->returnValue($dataMapper));
         $dataMapper->getPlainValue($input);
@@ -337,7 +410,8 @@ class DataMapperTest extends UnitTestCase
      */
     public function getPlainValueCallsGetUidOnDomainObjectInterfaceInput()
     {
-        $dataMapper = new DataMapper();
+        /** @var DataMapper $dataMapper */
+        $dataMapper = $this->createPartialMock(DataMapper::class, ['dummy']);
         $input = $this->createMock(\TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface::class);
 
         $input->expects($this->once())->method('getUid')->will($this->returnValue(23));
index b74c95c..6bd6855 100644 (file)
@@ -4085,4 +4085,12 @@ return [
             'Breaking-87193-DeprecatedFunctionalityRemoved.rst'
         ],
     ],
+    'TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper->__construct' => [
+        'numberOfMandatoryArguments' => 7,
+        'maximumNumberOfArguments' => 8,
+        'restFiles' => [
+            'Breaking-87305-UseConstructorInjectionInDataMapper.rst',
+            'Deprecation-87305-UseConstructorInjectionInDataMapper.rst',
+        ],
+    ],
 ];