diff --git a/typo3/sysext/form/Tests/Unit/Domain/Finishers/AbstractFinisherTest.php b/typo3/sysext/form/Tests/Unit/Domain/Finishers/AbstractFinisherTest.php
index 03fa36d93633cc803bf31d1ea4f6c9dada9d3c77..f7ace48098d897405ecd428f03e3a5858368b993 100644
--- a/typo3/sysext/form/Tests/Unit/Domain/Finishers/AbstractFinisherTest.php
+++ b/typo3/sysext/form/Tests/Unit/Domain/Finishers/AbstractFinisherTest.php
@@ -18,13 +18,13 @@ declare(strict_types=1);
 namespace TYPO3\CMS\Form\Tests\Unit\Domain\Finishers;
 
 use PHPUnit\Framework\Attributes\Test;
-use TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher;
 use TYPO3\CMS\Form\Domain\Finishers\Exception\FinisherException;
 use TYPO3\CMS\Form\Domain\Finishers\FinisherContext;
 use TYPO3\CMS\Form\Domain\Finishers\FinisherVariableProvider;
 use TYPO3\CMS\Form\Domain\Model\FormDefinition;
 use TYPO3\CMS\Form\Domain\Model\FormElements\StringableFormElementInterface;
 use TYPO3\CMS\Form\Domain\Runtime\FormRuntime;
+use TYPO3\CMS\Form\Tests\Unit\Domain\Finishers\Fixtures\AbstractFinisherFixture;
 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
 
 final class AbstractFinisherTest extends UnitTestCase
@@ -32,264 +32,99 @@ final class AbstractFinisherTest extends UnitTestCase
     #[Test]
     public function parseOptionReturnsNullIfOptionNameIsTranslation(): void
     {
-        $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
-            AbstractFinisher::class,
-            [],
-            '',
-            false
-        );
-
-        self::assertNull($mockAbstractFinisher->_call('parseOption', 'translation'));
+        $subject = new AbstractFinisherFixture();
+        self::assertNull($subject->parseOption('translation'));
     }
 
     #[Test]
     public function parseOptionReturnsNullIfOptionNameNotExistsWithinOptions(): void
     {
-        $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
-            AbstractFinisher::class,
-            [],
-            '',
-            false
-        );
-
-        $mockAbstractFinisher->_set('options', []);
-
-        self::assertNull($mockAbstractFinisher->_call('parseOption', 'foo'));
-    }
-
-    #[Test]
-    public function parseOptionReturnsNullIfOptionNameNotExistsWithinDefaultOptions(): void
-    {
-        $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
-            AbstractFinisher::class,
-            [],
-            '',
-            false
-        );
-
-        $mockAbstractFinisher->_set('options', []);
-
-        self::assertNull($mockAbstractFinisher->_call('parseOption', 'foo'));
-    }
-
-    #[Test]
-    public function parseOptionReturnsBoolOptionValuesAsBool(): void
-    {
-        $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
-            AbstractFinisher::class,
-            [],
-            '',
-            false
-        );
-
-        $mockAbstractFinisher->_set('options', [
-            'foo1' => false,
-        ]);
-
-        self::assertFalse($mockAbstractFinisher->_call('parseOption', 'foo1'));
+        $subject = new AbstractFinisherFixture();
+        $subject->options = [];
+        self::assertNull($subject->parseOption('foo'));
     }
 
     #[Test]
     public function parseOptionReturnsDefaultOptionValueIfOptionNameNotExistsWithinOptionsButWithinDefaultOptions(): void
     {
-        $expected = 'defaultValue';
-
-        $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
-            AbstractFinisher::class,
-            [],
-            '',
-            false,
-            false,
-            true,
-            [
-                'translateFinisherOption',
-            ]
-        );
-
-        $mockAbstractFinisher
-            ->method('translateFinisherOption')
-            ->willReturnArgument(0);
-
-        $mockAbstractFinisher->_set('options', []);
-        $mockAbstractFinisher->_set('defaultOptions', [
-            'subject' => $expected,
-        ]);
-
         $finisherContextMock = $this->createMock(FinisherContext::class);
-
         $formRuntimeMock = $this->createMock(FormRuntime::class);
         $formRuntimeMock->method('offsetExists')->with(self::anything())->willReturn(true);
         $formRuntimeMock->method('offsetGet')->with(self::anything())->willReturn(null);
-
         $finisherContextMock->method('getFormRuntime')->willReturn($formRuntimeMock);
-        $finisherContextMock->method('getFinisherVariableProvider')
-            ->willReturn(new FinisherVariableProvider());
-
-        $mockAbstractFinisher->_set('finisherContext', $finisherContextMock);
+        $finisherContextMock->method('getFinisherVariableProvider')->willReturn(new FinisherVariableProvider());
 
-        self::assertSame($expected, $mockAbstractFinisher->_call('parseOption', 'subject'));
+        $subject = new AbstractFinisherFixture();
+        $subject->options = [];
+        $subject->defaultOptions = [
+            'subject' => 'defaultValue',
+        ];
+        $subject->finisherContext = $finisherContextMock;
+        self::assertSame('defaultValue', $subject->parseOption('subject'));
     }
 
     #[Test]
     public function parseOptionReturnsDefaultOptionValueIfOptionValueIsAFormElementReferenceAndTheFormElementValueIsEmpty(): void
     {
-        $elementIdentifier = 'element-identifier-1';
-        $expected = 'defaultValue';
-
-        $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
-            AbstractFinisher::class,
-            [],
-            '',
-            false,
-            false,
-            true,
-            [
-                'translateFinisherOption',
-            ]
-        );
-
-        $mockAbstractFinisher
-            ->method('translateFinisherOption')
-            ->willReturnArgument(0);
-
-        $mockAbstractFinisher->_set('options', [
-            'subject' => '{' . $elementIdentifier . '}',
-        ]);
-        $mockAbstractFinisher->_set('defaultOptions', [
-            'subject' => $expected,
-        ]);
-
-        $finisherContextMock = $this->createMock(FinisherContext::class);
-
-        $formRuntimeMock = $this->createMock(FormRuntime::class);
-        $formRuntimeMock->method('offsetExists')->with($elementIdentifier)->willReturn(true);
-        $formRuntimeMock->method('offsetGet')->with($elementIdentifier)->willReturn('');
-
-        $finisherContextMock->method('getFormRuntime')->willReturn($formRuntimeMock);
-
-        $mockAbstractFinisher->_set('finisherContext', $finisherContextMock);
-
-        self::assertSame($expected, $mockAbstractFinisher->_call('parseOption', 'subject'));
-    }
-
-    #[Test]
-    public function parseOptionResolvesFormElementReferenceFromTranslation(): void
-    {
-        $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
-            AbstractFinisher::class,
-            [],
-            '',
-            false,
-            false,
-            true,
-            [
-                'translateFinisherOption',
-            ]
-        );
-
-        $elementIdentifier = 'element-identifier-1';
-        $elementValue = 'element-value-1';
-        $elementReferenceName = '{' . $elementIdentifier . '}';
-
-        $translationValue = 'subject: ' . $elementReferenceName;
-        $expected = 'subject: ' . $elementValue;
-
-        $mockAbstractFinisher
-            ->method('translateFinisherOption')
-            ->willReturn($translationValue);
-
-        $mockAbstractFinisher->_set('options', [
-            'subject' => '',
-        ]);
-
         $finisherContextMock = $this->createMock(FinisherContext::class);
-
         $formRuntimeMock = $this->createMock(FormRuntime::class);
-        $formRuntimeMock->method('offsetExists')->with($elementIdentifier)->willReturn(true);
-        $formRuntimeMock->method('offsetGet')->with($elementIdentifier)->willReturn($elementValue);
-
+        $formRuntimeMock->method('offsetExists')->with(self::anything())->willReturn(true);
+        $formRuntimeMock->method('offsetGet')->with(self::anything())->willReturn('');
         $finisherContextMock->method('getFormRuntime')->willReturn($formRuntimeMock);
 
-        $mockAbstractFinisher->_set('finisherContext', $finisherContextMock);
-
-        self::assertSame($expected, $mockAbstractFinisher->_call('parseOption', 'subject'));
+        $subject = new AbstractFinisherFixture();
+        $subject->options = [
+            'subject' => '{element-identifier-1}',
+        ];
+        $subject->defaultOptions = [
+            'subject' => 'defaultValue',
+        ];
+        $subject->finisherContext = $finisherContextMock;
+        self::assertSame('defaultValue', $subject->parseOption('subject'));
     }
 
     #[Test]
     public function substituteRuntimeReferencesReturnsArrayIfInputIsArray(): void
     {
-        $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
-            AbstractFinisher::class,
-            [],
-            '',
-            false
-        );
-
         $formRuntimeMock = $this->createMock(FormRuntime::class);
-
         $input = ['bar', 'foobar', ['x', 'y']];
         $expected = ['bar', 'foobar', ['x', 'y']];
-
-        self::assertSame($expected, $mockAbstractFinisher->_call('substituteRuntimeReferences', $input, $formRuntimeMock));
+        $subject = new AbstractFinisherFixture();
+        self::assertSame($expected, $subject->substituteRuntimeReferences($input, $formRuntimeMock));
     }
 
     #[Test]
     public function substituteRuntimeReferencesReturnsStringIfInputIsString(): void
     {
-        $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
-            AbstractFinisher::class,
-            [],
-            '',
-            false
-        );
-
         $formRuntimeMock = $this->createMock(FormRuntime::class);
-
         $input = 'foobar';
         $expected = 'foobar';
-
-        self::assertSame($expected, $mockAbstractFinisher->_call('substituteRuntimeReferences', $input, $formRuntimeMock));
+        $subject = new AbstractFinisherFixture();
+        self::assertSame($expected, $subject->substituteRuntimeReferences($input, $formRuntimeMock));
     }
 
     #[Test]
     public function substituteRuntimeReferencesReturnsValueFromFormRuntimeIfInputReferenceAFormElementIdentifierWhoseValueIsAString(): void
     {
-        $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
-            AbstractFinisher::class,
-            [],
-            '',
-            false
-        );
-
         $elementIdentifier = 'element-identifier-1';
         $input = '{' . $elementIdentifier . '}';
         $expected = 'element-value';
-
         $formRuntimeMock = $this->createMock(FormRuntime::class);
         $formRuntimeMock->method('offsetExists')->with($elementIdentifier)->willReturn(true);
         $formRuntimeMock->method('offsetGet')->with($elementIdentifier)->willReturn($expected);
-
-        self::assertSame($expected, $mockAbstractFinisher->_call('substituteRuntimeReferences', $input, $formRuntimeMock));
+        $subject = new AbstractFinisherFixture();
+        self::assertSame($expected, $subject->substituteRuntimeReferences($input, $formRuntimeMock));
     }
 
     #[Test]
     public function substituteRuntimeReferencesReturnsValueFromFormRuntimeIfInputReferenceMultipleFormElementIdentifierWhoseValueIsAString(): void
     {
-        $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
-            AbstractFinisher::class,
-            [],
-            '',
-            false
-        );
-
         $elementIdentifier1 = 'element-identifier-1';
         $elementValue1 = 'element-value-1';
         $elementIdentifier2 = 'element-identifier-2';
         $elementValue2 = 'element-value-2';
-
         $input = '{' . $elementIdentifier1 . '},{' . $elementIdentifier2 . '}';
         $expected = $elementValue1 . ',' . $elementValue2;
-
         $formRuntimeMock = $this->createMock(FormRuntime::class);
         $formRuntimeMock->method('offsetExists')->willReturnMap([
             [$elementIdentifier1, true],
@@ -299,46 +134,30 @@ final class AbstractFinisherTest extends UnitTestCase
             [$elementIdentifier1, $elementValue1],
             [$elementIdentifier2, $elementValue2],
         ]);
-
-        self::assertSame($expected, $mockAbstractFinisher->_call('substituteRuntimeReferences', $input, $formRuntimeMock));
+        $subject = new AbstractFinisherFixture();
+        self::assertSame($expected, $subject->substituteRuntimeReferences($input, $formRuntimeMock));
     }
 
     #[Test]
     public function substituteRuntimeReferencesReturnsValueFromFormRuntimeIfInputReferenceAFormElementIdentifierWhoseValueIsAnArray(): void
     {
-        $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
-            AbstractFinisher::class,
-            [],
-            '',
-            false
-        );
-
         $elementIdentifier = 'element-identifier-1';
         $input = '{' . $elementIdentifier . '}';
         $expected = ['bar', 'foobar'];
-
         $formRuntimeMock = $this->createMock(FormRuntime::class);
         $formRuntimeMock->method('offsetExists')->with($elementIdentifier)->willReturn(true);
         $formRuntimeMock->method('offsetGet')->with($elementIdentifier)->willReturn($expected);
-
-        self::assertSame($expected, $mockAbstractFinisher->_call('substituteRuntimeReferences', $input, $formRuntimeMock));
+        $subject = new AbstractFinisherFixture();
+        self::assertSame($expected, $subject->substituteRuntimeReferences($input, $formRuntimeMock));
     }
 
     #[Test]
     public function substituteRuntimeReferencesReturnsValueFromFormRuntimeIfInputIsArrayAndSomeItemsReferenceAFormElementIdentifierWhoseValueIsAnArray(): void
     {
-        $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
-            AbstractFinisher::class,
-            [],
-            '',
-            false
-        );
-
         $elementIdentifier1 = 'element-identifier-1';
         $elementValue1 = ['klaus', 'fritz'];
         $elementIdentifier2 = 'element-identifier-2';
         $elementValue2 = ['stan', 'steve'];
-
         $input = [
             '{' . $elementIdentifier1 . '}',
             'static value',
@@ -357,7 +176,6 @@ final class AbstractFinisherTest extends UnitTestCase
                 ['stan', 'steve'],
             ],
         ];
-
         $formRuntimeMock = $this->createMock(FormRuntime::class);
         $formRuntimeMock->method('offsetExists')->willReturnMap([
             [$elementIdentifier1, true],
@@ -367,71 +185,43 @@ final class AbstractFinisherTest extends UnitTestCase
             [$elementIdentifier1, $elementValue1],
             [$elementIdentifier2, $elementValue2],
         ]);
-
-        self::assertSame($expected, $mockAbstractFinisher->_call('substituteRuntimeReferences', $input, $formRuntimeMock));
+        $subject = new AbstractFinisherFixture();
+        self::assertSame($expected, $subject->substituteRuntimeReferences($input, $formRuntimeMock));
     }
 
     #[Test]
     public function substituteRuntimeReferencesReturnsNoReplacedValueIfInputReferenceANonExistingFormElement(): void
     {
-        $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
-            AbstractFinisher::class,
-            [],
-            '',
-            false
-        );
-
         $elementIdentifier = 'element-identifier-1';
         $input = '{' . $elementIdentifier . '}';
         $expected = '{' . $elementIdentifier . '}';
-
         $formRuntimeMock = $this->createMock(FormRuntime::class);
         $formRuntimeMock->method('offsetExists')->with($elementIdentifier)->willReturn(true);
         $formRuntimeMock->method('offsetGet')->with($elementIdentifier)->willReturn($expected);
-
         $finisherContextMock = $this->createMock(FinisherContext::class);
         $finisherContextMock->method('getFinisherVariableProvider')->willReturn(new FinisherVariableProvider());
-        $mockAbstractFinisher->_set('finisherContext', $finisherContextMock);
-
-        self::assertSame($expected, $mockAbstractFinisher->_call('substituteRuntimeReferences', $input, $formRuntimeMock));
+        $subject = new AbstractFinisherFixture();
+        $subject->finisherContext = $finisherContextMock;
+        self::assertSame($expected, $subject->substituteRuntimeReferences($input, $formRuntimeMock));
     }
 
     #[Test]
     public function substituteRuntimeReferencesReturnsTimestampIfInputIsATimestampRequestTrigger(): void
     {
-        $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
-            AbstractFinisher::class,
-            [],
-            '',
-            false
-        );
-
         $input = '{__currentTimestamp}';
         $expected = '#^([0-9]{10})$#';
-
         $formRuntimeMock = $this->createMock(FormRuntime::class);
-
-        self::assertMatchesRegularExpression(
-            $expected,
-            (string)$mockAbstractFinisher->_call('substituteRuntimeReferences', $input, $formRuntimeMock)
-        );
+        $subject = new AbstractFinisherFixture();
+        self::assertMatchesRegularExpression($expected, (string)$subject->substituteRuntimeReferences($input, $formRuntimeMock));
     }
 
     #[Test]
     public function substituteRuntimeReferencesReturnsResolvesElementIdentifiersInArrayKeys(): void
     {
-        $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
-            AbstractFinisher::class,
-            [],
-            '',
-            false
-        );
-
         $elementIdentifier1 = 'element-identifier-1';
         $elementValue1 = 'norbert';
         $elementIdentifier2 = 'element-identifier-2';
         $elementValue2 = ['stan', 'steve'];
-
         $input = [
             '{' . $elementIdentifier1 . '}' => [
                 'lisa',
@@ -444,7 +234,6 @@ final class AbstractFinisherTest extends UnitTestCase
                 ['stan', 'steve'],
             ],
         ];
-
         $formRuntimeMock = $this->createMock(FormRuntime::class);
         $formRuntimeMock->method('offsetExists')->willReturnMap([
             [$elementIdentifier1, true],
@@ -454,8 +243,8 @@ final class AbstractFinisherTest extends UnitTestCase
             [$elementIdentifier1, $elementValue1],
             [$elementIdentifier2, $elementValue2],
         ]);
-
-        self::assertSame($expected, $mockAbstractFinisher->_call('substituteRuntimeReferences', $input, $formRuntimeMock));
+        $subject = new AbstractFinisherFixture();
+        self::assertSame($expected, $subject->substituteRuntimeReferences($input, $formRuntimeMock));
     }
 
     #[Test]
@@ -465,7 +254,6 @@ final class AbstractFinisherTest extends UnitTestCase
         $formRuntimeMock = $this->createMock(FormRuntime::class);
         $formRuntimeMock->method('offsetExists')->with('date-1')->willReturn(true);
         $formRuntimeMock->method('offsetGet')->with('date-1')->willReturn($date);
-
         $stringableElement = new class () implements StringableFormElementInterface {
             /**
              * @param \DateTimeInterface $value
@@ -478,20 +266,8 @@ final class AbstractFinisherTest extends UnitTestCase
         $formDefinitionMock = $this->createMock(FormDefinition::class);
         $formDefinitionMock->method('getElementByIdentifier')->with('date-1')->willReturn($stringableElement);
         $formRuntimeMock->method('getFormDefinition')->willReturn($formDefinitionMock);
-
-        $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
-            AbstractFinisher::class,
-            [],
-            '',
-            false
-        );
-        $result = $mockAbstractFinisher->_call(
-            'substituteRuntimeReferences',
-            'When: {date-1}',
-            $formRuntimeMock
-        );
-
-        self::assertSame('When: 2019-11-22', $result);
+        $subject = new AbstractFinisherFixture();
+        self::assertSame('When: 2019-11-22', $subject->substituteRuntimeReferences('When: {date-1}', $formRuntimeMock));
     }
 
     #[Test]
@@ -500,55 +276,25 @@ final class AbstractFinisherTest extends UnitTestCase
         $formRuntimeMock = $this->createMock(FormRuntime::class);
         $formRuntimeMock->method('offsetExists')->with('date-1')->willReturn(true);
         $formRuntimeMock->method('offsetGet')->with('date-1')->willReturn(new \DateTime());
-
         $formDefinitionMock = $this->createMock(FormDefinition::class);
         $formRuntimeMock->method('getFormDefinition')->willReturn($formDefinitionMock);
-
-        $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
-            AbstractFinisher::class,
-            [],
-            '',
-            false
-        );
-
         $this->expectException(FinisherException::class);
         $this->expectExceptionCode(1574362327);
-
-        $mockAbstractFinisher->_call(
-            'substituteRuntimeReferences',
-            'When: {date-1}',
-            $formRuntimeMock
-        );
+        $subject = new AbstractFinisherFixture();
+        $subject->substituteRuntimeReferences('When: {date-1}', $formRuntimeMock);
     }
 
     #[Test]
     public function substituteRuntimeReferencesThrowsExceptionOnMultipleVariablesResolvedAsArray(): void
     {
-        $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
-            AbstractFinisher::class,
-            [],
-            '',
-            false
-        );
-
         $elementIdentifier = 'element-identifier-1';
         $input = 'BEFORE {' . $elementIdentifier . '} AFTER';
-
         $formRuntimeMock = $this->createMock(FormRuntime::class);
         $formRuntimeMock->method('offsetExists')->with($elementIdentifier)->willReturn(true);
         $formRuntimeMock->method('offsetGet')->with($elementIdentifier)->willReturn(['value-1', 'value-2']);
-
-        $finisherContextMock = $this->createMock(FinisherContext::class);
-        $finisherContextMock->method('getFinisherVariableProvider')->willReturn(new FinisherVariableProvider());
-        $mockAbstractFinisher->_set('finisherContext', $finisherContextMock);
-
         $this->expectException(FinisherException::class);
         $this->expectExceptionCode(1519239265);
-
-        $mockAbstractFinisher->_call(
-            'substituteRuntimeReferences',
-            $input,
-            $formRuntimeMock
-        );
+        $subject = new AbstractFinisherFixture();
+        $subject->substituteRuntimeReferences($input, $formRuntimeMock);
     }
 }
diff --git a/typo3/sysext/form/Tests/Unit/Domain/Finishers/Fixtures/AbstractFinisherFixture.php b/typo3/sysext/form/Tests/Unit/Domain/Finishers/Fixtures/AbstractFinisherFixture.php
new file mode 100644
index 0000000000000000000000000000000000000000..53eaeee6c5e317e09821c94efc554b3fa8f25397
--- /dev/null
+++ b/typo3/sysext/form/Tests/Unit/Domain/Finishers/Fixtures/AbstractFinisherFixture.php
@@ -0,0 +1,57 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+/*
+ * Inspired by and partially taken from the Neos.Form package (www.neos.io)
+ */
+
+namespace TYPO3\CMS\Form\Tests\Unit\Domain\Finishers\Fixtures;
+
+use TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher;
+use TYPO3\CMS\Form\Domain\Runtime\FormRuntime;
+
+final class AbstractFinisherFixture extends AbstractFinisher
+{
+    public $options = [];
+    public $defaultOptions = [];
+    public $finisherContext;
+
+    protected function executeInternal()
+    {
+        return null;
+    }
+
+    public function parseOption(string $optionName)
+    {
+        return parent::parseOption($optionName);
+    }
+
+    protected function translateFinisherOption(
+        $subject,
+        FormRuntime $formRuntime,
+        string $optionName,
+        $optionValue,
+        array $translationOptions
+    ) {
+        return $subject;
+    }
+
+    public function substituteRuntimeReferences($needle, FormRuntime $formRuntime)
+    {
+        return parent::substituteRuntimeReferences($needle, $formRuntime);
+    }
+}
diff --git a/typo3/sysext/form/Tests/Unit/Domain/FormElements/AbstractSectionTest.php b/typo3/sysext/form/Tests/Unit/Domain/FormElements/AbstractSectionTest.php
index 546207b6a95f3aa7bfcc60b8e39b66d40cb1c811..d27698f861e383244c8fdae4ba62a90ae5d65608 100644
--- a/typo3/sysext/form/Tests/Unit/Domain/FormElements/AbstractSectionTest.php
+++ b/typo3/sysext/form/Tests/Unit/Domain/FormElements/AbstractSectionTest.php
@@ -24,10 +24,9 @@ use TYPO3\CMS\Form\Domain\Exception\TypeDefinitionNotFoundException;
 use TYPO3\CMS\Form\Domain\Exception\TypeDefinitionNotValidException;
 use TYPO3\CMS\Form\Domain\Model\FormDefinition;
 use TYPO3\CMS\Form\Domain\Model\FormElements\AbstractSection;
-use TYPO3\CMS\Form\Domain\Model\FormElements\Section;
 use TYPO3\CMS\Form\Domain\Model\FormElements\UnknownFormElement;
+use TYPO3\CMS\Form\Tests\Unit\Domain\FormElements\Fixtures\AbstractSectionFixture;
 use TYPO3\CMS\Form\Tests\Unit\Domain\FormElements\Fixtures\TestingFormElement;
-use TYPO3\CMS\Form\Tests\Unit\Domain\FormElements\Fixtures\TestingSection;
 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
 
 final class AbstractSectionTest extends UnitTestCase
@@ -39,73 +38,36 @@ final class AbstractSectionTest extends UnitTestCase
     {
         $this->expectException(IdentifierNotValidException::class);
         $this->expectExceptionCode(1477082501);
-
-        // Section inherits from AbstractSection and serves as concrete implementation
-        new Section('', 'foobar');
+        new AbstractSectionFixture('', 'foobar');
     }
 
     #[Test]
     public function constructMustNotThrowExceptionWhenIdentifierIsNonEmptyString(): void
     {
-        $section = new Section('foobar', 'foobar');
-        self::assertInstanceOf(AbstractSection::class, $section);
+        $subject = new AbstractSectionFixture('foobar', '');
+        self::assertInstanceOf(AbstractSection::class, $subject);
     }
 
     #[Test]
     public function createElementThrowsExceptionIfTypeDefinitionNotFoundAndSkipUnknownElementsIsFalse(): void
     {
-        $rootForm = $this->getMockBuilder(FormDefinition::class)
-            ->onlyMethods(['getRenderingOptions', 'getTypeDefinitions'])
-            ->disableOriginalConstructor()
-            ->getMock();
-        $rootForm
-            ->method('getRenderingOptions')
-            ->willReturn(['skipUnknownElements' => false]);
-        $rootForm
-            ->method('getTypeDefinitions')
-            ->willReturn([]);
-
-        $mockAbstractSection = $this->getAccessibleMockForAbstractClass(
-            AbstractSection::class,
-            [],
-            '',
-            false,
-            false,
-            true,
-            [
-                'getRootForm',
-            ]
-        );
-
-        $mockAbstractSection
-            ->expects(self::once())
-            ->method('getRootForm')
-            ->willReturn($rootForm);
-
+        $rootForm = $this->createMock(FormDefinition::class);
         $this->expectException(TypeDefinitionNotFoundException::class);
         $this->expectExceptionCode(1382364019);
-
-        $mockAbstractSection->_call('createElement', '', '');
+        $subject = new AbstractSectionFixture('identifier', '');
+        $subject->setParentRenderable($rootForm);
+        $subject->createElement('', '');
     }
 
     #[Test]
     public function createElementReturnsUnknownElementsIfTypeDefinitionIsNotFoundAndSkipUnknownElementsIsTrue(): void
     {
-        $rootForm = $this->getMockBuilder(FormDefinition::class)
-            ->onlyMethods(['getRenderingOptions', 'getTypeDefinitions'])
-            ->disableOriginalConstructor()
-            ->getMock();
-        $rootForm
-            ->method('getRenderingOptions')
-            ->willReturn(['skipUnknownElements' => true]);
-        $rootForm
-            ->method('getTypeDefinitions')
-            ->willReturn([]);
-        $section = new TestingSection($rootForm);
-
+        $rootForm = $this->createMock(FormDefinition::class);
+        $rootForm->method('getRenderingOptions')->willReturn(['skipUnknownElements' => true]);
         GeneralUtility::addInstance(UnknownFormElement::class, new UnknownFormElement('foo', 'bar'));
-        $result = $section->createElement('foo', 'bar');
-
+        $subject = new AbstractSectionFixture('testing', '');
+        $subject->setParentRenderable($rootForm);
+        $result = $subject->createElement('foo', 'bar');
         self::assertInstanceOf(UnknownFormElement::class, $result);
         self::assertSame('foo', $result->getIdentifier());
         self::assertSame('bar', $result->getType());
@@ -114,89 +76,50 @@ final class AbstractSectionTest extends UnitTestCase
     #[Test]
     public function createElementThrowsExceptionIfTypeDefinitionIsNotSet(): void
     {
-        $rootForm = $this->getMockBuilder(FormDefinition::class)
-            ->onlyMethods(['getRenderingOptions', 'getTypeDefinitions'])
-            ->disableOriginalConstructor()
-            ->getMock();
-        $rootForm
-            ->method('getRenderingOptions')
-            ->willReturn(['skipUnknownElements' => true]);
-        $rootForm
-            ->method('getTypeDefinitions')
-            ->willReturn(['foobar' => []]);
-        $section = new TestingSection($rootForm);
-
         $this->expectException(TypeDefinitionNotFoundException::class);
         $this->expectExceptionCode(1325689855);
-
-        $section->createElement('id', 'foobar');
+        $rootForm = $this->createMock(FormDefinition::class);
+        $rootForm->method('getTypeDefinitions')->willReturn(['foobar' => []]);
+        $subject = new AbstractSectionFixture('testing', '');
+        $subject->setParentRenderable($rootForm);
+        $subject->createElement('id', 'foobar');
     }
 
     #[Test]
     public function createElementThrowsExceptionIfTypeDefinitionNotInstanceOfFormElementInterface(): void
     {
-        $rootForm = $this->getMockBuilder(FormDefinition::class)
-            ->onlyMethods(['getRenderingOptions', 'getTypeDefinitions'])
-            ->disableOriginalConstructor()
-            ->getMock();
-        $rootForm
-            ->method('getRenderingOptions')
-            ->willReturn([]);
-        $rootForm
-            ->method('getTypeDefinitions')
-            ->willReturn(
-                [
-                    'foobar' => [
-                        'implementationClassName' => self::class,
-                    ],
-                ]
-            );
-        $section = new TestingSection($rootForm);
-
-        GeneralUtility::addInstance(self::class, $this);
-
         $this->expectException(TypeDefinitionNotValidException::class);
         $this->expectExceptionCode(1327318156);
-        $section->createElement('id', 'foobar');
+        $rootForm = $this->createMock(FormDefinition::class);
+        $rootForm->method('getTypeDefinitions')->willReturn([
+            'foobar' => [
+                'implementationClassName' => self::class,
+            ],
+        ]);
+        $subject = new AbstractSectionFixture('testing', '');
+        $subject->setParentRenderable($rootForm);
+        GeneralUtility::addInstance(self::class, $this);
+        $subject->createElement('id', 'foobar');
     }
 
     #[Test]
     public function createElementExpectedToAddAndInitializeElement(): void
     {
-        $implementationMock = $this->createPartialMock(TestingFormElement::class, ['setOptions', 'initializeFormElement']);
-
+        $implementationMock = $this->createMock(TestingFormElement::class);
         $typeDefinition = [
             'foo' => 'bar',
             'implementationClassName' => get_class($implementationMock),
             'fizz' => 'buzz',
         ];
-
         $typeDefinitionWithoutImplementationClassName = $typeDefinition;
         unset($typeDefinitionWithoutImplementationClassName['implementationClassName']);
-
-        $implementationMock
-            ->expects(self::once())
-            ->method('initializeFormElement');
-
-        $implementationMock
-            ->expects(self::once())
-            ->method('setOptions')
-            ->with($typeDefinitionWithoutImplementationClassName);
-
-        $rootForm = $this->getMockBuilder(FormDefinition::class)
-            ->onlyMethods(['getRenderingOptions', 'getTypeDefinitions'])
-            ->disableOriginalConstructor()
-            ->getMock();
-        $rootForm
-            ->method('getRenderingOptions')
-            ->willReturn([]);
-        $rootForm
-            ->method('getTypeDefinitions')
-            ->willReturn(['foobar' => $typeDefinition]);
-        $section = new TestingSection($rootForm);
-
+        $implementationMock->expects(self::once())->method('initializeFormElement');
+        $implementationMock->expects(self::once())->method('setOptions')->with($typeDefinitionWithoutImplementationClassName);
+        $rootForm = $this->createMock(FormDefinition::class);
+        $rootForm->method('getTypeDefinitions')->willReturn(['foobar' => $typeDefinition]);
+        $subject = new AbstractSectionFixture('testing', '');
+        $subject->setParentRenderable($rootForm);
         GeneralUtility::addInstance(get_class($implementationMock), $implementationMock);
-
-        $section->createElement('id', 'foobar');
+        $subject->createElement('id', 'foobar');
     }
 }
diff --git a/typo3/sysext/form/Tests/Unit/Domain/FormElements/Fixtures/TestingSection.php b/typo3/sysext/form/Tests/Unit/Domain/FormElements/Fixtures/AbstractSectionFixture.php
similarity index 60%
rename from typo3/sysext/form/Tests/Unit/Domain/FormElements/Fixtures/TestingSection.php
rename to typo3/sysext/form/Tests/Unit/Domain/FormElements/Fixtures/AbstractSectionFixture.php
index 3e19c2dcc471719216d367e521eb60563f6f33ea..7a6f5d36d1a5522f491c73c1f20b18bdc882d160 100644
--- a/typo3/sysext/form/Tests/Unit/Domain/FormElements/Fixtures/TestingSection.php
+++ b/typo3/sysext/form/Tests/Unit/Domain/FormElements/Fixtures/AbstractSectionFixture.php
@@ -17,21 +17,6 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Form\Tests\Unit\Domain\FormElements\Fixtures;
 
-use TYPO3\CMS\Form\Domain\Model\FormDefinition;
 use TYPO3\CMS\Form\Domain\Model\FormElements\AbstractSection;
 
-/**
- * Testing subclass of the abstract class.
- */
-class TestingSection extends AbstractSection
-{
-    public function __construct(private readonly FormDefinition $rootForm)
-    {
-        parent::__construct('testing_section', '');
-    }
-
-    public function getRootForm(): FormDefinition
-    {
-        return $this->rootForm;
-    }
-}
+final class AbstractSectionFixture extends AbstractSection {}
diff --git a/typo3/sysext/frontend/Tests/Unit/ContentObject/Menu/AbstractMenuContentObjectTest.php b/typo3/sysext/frontend/Tests/Unit/ContentObject/Menu/AbstractMenuContentObjectTest.php
index b3160646d40513dcd35ac6df855c2de495499833..5aa12651f600864799ca074b0a5c3e521304e75c 100644
--- a/typo3/sysext/frontend/Tests/Unit/ContentObject/Menu/AbstractMenuContentObjectTest.php
+++ b/typo3/sysext/frontend/Tests/Unit/ContentObject/Menu/AbstractMenuContentObjectTest.php
@@ -20,8 +20,6 @@ namespace TYPO3\CMS\Frontend\Tests\Unit\ContentObject\Menu;
 use Doctrine\DBAL\Result;
 use PHPUnit\Framework\Attributes\DataProvider;
 use PHPUnit\Framework\Attributes\Test;
-use PHPUnit\Framework\MockObject\MockObject;
-use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
 use TYPO3\CMS\Core\Context\Context;
 use TYPO3\CMS\Core\Context\LanguageAspect;
 use TYPO3\CMS\Core\Database\Connection;
@@ -32,31 +30,24 @@ use TYPO3\CMS\Core\Domain\Repository\PageRepository;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
-use TYPO3\CMS\Frontend\ContentObject\Menu\AbstractMenuContentObject;
 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
 use TYPO3\CMS\Frontend\Page\PageInformation;
-use TYPO3\TestingFramework\Core\AccessibleObjectInterface;
+use TYPO3\CMS\Frontend\Tests\Unit\ContentObject\Menu\Fixtures\AbstractMenuContentObjectFixture;
 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
 
 final class AbstractMenuContentObjectTest extends UnitTestCase
 {
-    protected AbstractMenuContentObject&MockObject&AccessibleObjectInterface $subject;
-
     protected function tearDown(): void
     {
         GeneralUtility::purgeInstances();
         parent::tearDown();
     }
 
-    /**
-     * Prepares a test for the method sectionIndex
-     */
-    protected function prepareSectionIndexTest(): void
+    private function prepareSectionIndexTest(): void
     {
         $connectionMock = $this->createMock(Connection::class);
         $connectionMock->method('getExpressionBuilder')->willReturn(new ExpressionBuilder($connectionMock));
         $connectionMock->method('quoteIdentifier')->willReturnArgument(0)->withAnyParameters();
-
         $connectionPoolMock = $this->createMock(ConnectionPool::class);
         $connectionPoolMock->method('getConnectionForTable')->with('tt_content')->willReturn($connectionMock);
         GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolMock);
@@ -66,25 +57,23 @@ final class AbstractMenuContentObjectTest extends UnitTestCase
     public function sectionIndexReturnsEmptyArrayIfTheRequestedPageCouldNotBeFetched(): void
     {
         $this->prepareSectionIndexTest();
-        $pageRepository = $this->getMockBuilder(PageRepository::class)->disableOriginalConstructor()->getMock();
+        $pageRepository = $this->createMock(PageRepository::class);
         $pageRepository->expects(self::once())->method('getPage')->willReturn([]);
-        $this->subject = $this->getAccessibleMockForAbstractClass(AbstractMenuContentObject::class);
-        $this->subject->_set('sys_page', $pageRepository);
-        $result = $this->subject->_call('sectionIndex', 'field');
-        self::assertEquals([], $result);
+        $subject = new AbstractMenuContentObjectFixture();
+        $subject->sys_page = $pageRepository;
+        self::assertEquals([], $subject->sectionIndex('field'));
     }
 
     #[Test]
     public function sectionIndexUsesTheInternalIdIfNoPageIdWasGiven(): void
     {
         $this->prepareSectionIndexTest();
-        $pageRepository = $this->getMockBuilder(PageRepository::class)->disableOriginalConstructor()->getMock();
+        $pageRepository = $this->createMock(PageRepository::class);
         $pageRepository->expects(self::once())->method('getPage')->with(10)->willReturn([]);
-        $this->subject = $this->getAccessibleMockForAbstractClass(AbstractMenuContentObject::class);
-        $this->subject->_set('sys_page', $pageRepository);
-        $this->subject->_set('id', 10);
-        $result = $this->subject->_call('sectionIndex', 'field');
-        self::assertEquals([], $result);
+        $subject = new AbstractMenuContentObjectFixture();
+        $subject->sys_page = $pageRepository;
+        $subject->id = 10;
+        self::assertEquals([], $subject->sectionIndex('field'));
     }
 
     #[Test]
@@ -93,45 +82,39 @@ final class AbstractMenuContentObjectTest extends UnitTestCase
         $this->expectException(\UnexpectedValueException::class);
         $this->expectExceptionCode(1337334849);
         $this->prepareSectionIndexTest();
-        $pageRepository = $this->getMockBuilder(PageRepository::class)->disableOriginalConstructor()->getMock();
+        $pageRepository = $this->createMock(PageRepository::class);
         $pageRepository->expects(self::once())->method('getPage')->willReturn(['uid' => 10]);
-        $this->subject = $this->getAccessibleMockForAbstractClass(AbstractMenuContentObject::class);
-        $this->subject->_set('sys_page', $pageRepository);
-        $this->subject->_set('id', 10);
-
-        $cObject = $this->getMockBuilder(ContentObjectRenderer::class)->disableOriginalConstructor()->getMock();
+        $cObject = $this->createMock(ContentObjectRenderer::class);
         $cObject->expects(self::once())->method('exec_getQuery')->willReturn(0);
-        $this->subject->_set('parent_cObj', $cObject);
-
-        $this->subject->_call('sectionIndex', 'field');
+        $subject = new AbstractMenuContentObjectFixture();
+        $subject->sys_page = $pageRepository;
+        $subject->id = 10;
+        $subject->parent_cObj = $cObject;
+        $subject->sectionIndex('field');
     }
 
     #[Test]
     public function sectionIndexReturnsOverlaidRowBasedOnTheLanguageOfTheGivenPage(): void
     {
+        $this->prepareSectionIndexTest();
         $statementMock = $this->createMock(Result::class);
         $statementMock->expects(self::exactly(2))->method('fetchAssociative')->willReturn(['uid' => 0, 'header' => 'NOT_OVERLAID'], false);
-
-        $this->prepareSectionIndexTest();
-        $this->subject = $this->getAccessibleMockForAbstractClass(AbstractMenuContentObject::class);
-        $this->subject->_set('mconf', [
+        $subject = new AbstractMenuContentObjectFixture();
+        $subject->mconf = [
             'sectionIndex.' => [
                 'type' => 'all',
             ],
-        ]);
+        ];
         $context = GeneralUtility::makeInstance(Context::class);
         $context->setAspect('language', new LanguageAspect(1, 1, LanguageAspect::OVERLAYS_MIXED));
-
         $pageRepository = $this->getMockBuilder(PageRepository::class)->setConstructorArgs([$context])->onlyMethods(['init', 'getPage', 'getLanguageOverlay'])->getMock();
         $pageRepository->expects(self::once())->method('getPage')->willReturn(['sys_language_uid' => 1]);
         $pageRepository->expects(self::once())->method('getLanguageOverlay')->willReturn(['uid' => 0, 'header' => 'OVERLAID']);
-        $this->subject->_set('sys_page', $pageRepository);
-
-        $cObject = $this->getMockBuilder(ContentObjectRenderer::class)->getMock();
+        $subject->sys_page = $pageRepository;
+        $cObject = $this->createMock(ContentObjectRenderer::class);
         $cObject->expects(self::once())->method('exec_getQuery')->willReturn($statementMock);
-        $this->subject->_set('parent_cObj', $cObject);
-
-        $result = $this->subject->_call('sectionIndex', 'field');
+        $subject->parent_cObj = $cObject;
+        $result = $subject->sectionIndex('field');
         self::assertEquals('OVERLAID', $result[0]['title']);
     }
 
@@ -177,28 +160,23 @@ final class AbstractMenuContentObjectTest extends UnitTestCase
     #[Test]
     public function sectionIndexFilters(int $expectedAmount, array $dataRow): void
     {
+        $this->prepareSectionIndexTest();
         $statementMock = $this->createMock(Result::class);
         $statementMock->method('fetchAssociative')->willReturn($dataRow, false);
-
-        $this->prepareSectionIndexTest();
-        $this->subject = $this->getAccessibleMockForAbstractClass(AbstractMenuContentObject::class);
-        $this->subject->_set('mconf', [
+        $subject = new AbstractMenuContentObjectFixture();
+        $subject->mconf = [
             'sectionIndex.' => [
                 'type' => 'header',
             ],
-        ]);
-
-        $pageRepository = $this->getMockBuilder(PageRepository::class)->disableOriginalConstructor()->getMock();
+        ];
+        $pageRepository = $this->createMock(PageRepository::class);
         $pageRepository->expects(self::once())->method('getPage')->willReturn(['sys_language_uid' => 1]);
         $pageRepository->expects(self::once())->method('getPage')->willReturn([]);
-        $this->subject->_set('sys_page', $pageRepository);
-
-        $cObject = $this->getMockBuilder(ContentObjectRenderer::class)->getMock();
+        $subject->sys_page = $pageRepository;
+        $cObject = $this->createMock(ContentObjectRenderer::class);
         $cObject->expects(self::once())->method('exec_getQuery')->willReturn($statementMock);
-        $this->subject->_set('parent_cObj', $cObject);
-
-        $result = $this->subject->_call('sectionIndex', 'field');
-        self::assertCount($expectedAmount, $result);
+        $subject->parent_cObj = $cObject;
+        self::assertCount($expectedAmount, $subject->sectionIndex('field'));
     }
 
     public static function sectionIndexQueriesWithDifferentColPosDataProvider(): array
@@ -239,38 +217,25 @@ final class AbstractMenuContentObjectTest extends UnitTestCase
     #[Test]
     public function sectionIndexQueriesWithDifferentColPos(array $configuration, string $colPosFromStdWrapValue, string $whereClausePrefix): void
     {
+        $this->prepareSectionIndexTest();
         $statementMock = $this->createMock(Result::class);
         $statementMock->method('fetchAssociative')->willReturn([]);
-
-        $this->prepareSectionIndexTest();
-        $this->subject = $this->getAccessibleMockForAbstractClass(AbstractMenuContentObject::class);
-        $this->subject->_set('mconf', ['sectionIndex.' => $configuration]);
-
+        $subject = new AbstractMenuContentObjectFixture();
+        $subject->mconf = ['sectionIndex.' => $configuration];
         $pageRepository = $this->getMockBuilder(PageRepository::class)->disableOriginalConstructor()->getMock();
         $pageRepository->expects(self::once())->method('getPage')->willReturn(['uid' => 12]);
-        $this->subject->_set('sys_page', $pageRepository);
-
+        $subject->sys_page = $pageRepository;
         $queryConfiguration = [
             'pidInList' => 12,
             'orderBy' => 'field',
             'languageField' => 'sys_language_uid',
             'where' => $whereClausePrefix,
         ];
-
-        $cObject = $this->getMockBuilder(ContentObjectRenderer::class)->getMock();
-        $cObject
-            ->expects(self::once())
-            ->method('stdWrapValue')
-            ->with('useColPos', $configuration)
-            ->willReturn($colPosFromStdWrapValue);
-        $cObject
-            ->expects(self::once())
-            ->method('exec_getQuery')
-            ->with('tt_content', $queryConfiguration)
-            ->willReturn($statementMock);
-        $this->subject->parent_cObj = $cObject;
-
-        $this->subject->_call('sectionIndex', 'field', 12);
+        $cObject = $this->createMock(ContentObjectRenderer::class);
+        $cObject->expects(self::once())->method('stdWrapValue')->with('useColPos', $configuration)->willReturn($colPosFromStdWrapValue);
+        $cObject->expects(self::once())->method('exec_getQuery')->with('tt_content', $queryConfiguration)->willReturn($statementMock);
+        $subject->parent_cObj = $cObject;
+        $subject->sectionIndex('field', 12);
     }
 
     public static function isItemStateChecksExcludeUidListDataProvider(): array
@@ -360,41 +325,26 @@ final class AbstractMenuContentObjectTest extends UnitTestCase
     #[Test]
     public function isItemStateChecksExcludeUidList(array $menuItems, string $excludeUidList, bool $expectedResult): void
     {
-        $subject = $this->getAccessibleMockForAbstractClass(AbstractMenuContentObject::class, [], '', true, true, true, ['getRuntimeCache']);
+        $this->prepareSectionIndexTest();
         $request = new ServerRequest();
         $pageInformation = new PageInformation();
         $pageInformation->setPageRecord([]);
         $request = $request->withAttribute('frontend.page.information', $pageInformation);
-        $subject->_set('request', $request);
-
-        $runtimeCacheMock = $this->getMockBuilder(FrontendInterface::class)->getMock();
-        $runtimeCacheMock->method('get')->with(self::anything())->willReturn(false);
-        $runtimeCacheMock->method('set')->with(self::anything());
-        $subject->method('getRuntimeCache')->willReturn($runtimeCacheMock);
-
-        $cObjectMock = $this->getMockBuilder(ContentObjectRenderer::class)->getMock();
-        $cObjectMock
-            ->expects(self::once())
-            ->method('stdWrapValue')
-            ->with('excludeUidList', ['excludeUidList' => $excludeUidList])
-            ->willReturn($excludeUidList);
-
+        $subject = new AbstractMenuContentObjectFixture();
+        $subject->request = $request;
+        $cObjectMock = $this->createMock(ContentObjectRenderer::class);
+        $cObjectMock->expects(self::once())->method('stdWrapValue')->with('excludeUidList', ['excludeUidList' => $excludeUidList])->willReturn($excludeUidList);
         $typoScriptFrontendControllerMock = $this->createMock(TypoScriptFrontendController::class);
         $cObjectMock->method('getTypoScriptFrontendController')->willReturn($typoScriptFrontendControllerMock);
-
         $subject->parent_cObj = $cObjectMock;
-
-        $this->prepareSectionIndexTest();
-
-        $pageRepository = $this->getMockBuilder(PageRepository::class)->disableOriginalConstructor()->getMock();
+        $pageRepository = $this->createMock(PageRepository::class);
         $pageRepository->expects(self::once())->method('getMenu')->willReturn($menuItems);
-        $subject->_set('sys_page', $pageRepository);
-        $subject->_set('menuArr', [
+        $subject->sys_page = $pageRepository;
+        $subject->menuArr = [
             0 => ['uid' => 42],
-        ]);
-        $subject->_set('conf', ['excludeUidList' => $excludeUidList]);
-
-        self::assertEquals($expectedResult, $subject->_call('isItemState', 'IFSUB', 0));
+        ];
+        $subject->conf = ['excludeUidList' => $excludeUidList];
+        self::assertEquals($expectedResult, $subject->isItemState('IFSUB', 0));
     }
 
     public static function menuTypoLinkCreatesExpectedTypoLinkConfigurationDataProvider(): array
@@ -559,13 +509,11 @@ final class AbstractMenuContentObjectTest extends UnitTestCase
     public function menuTypoLinkCreatesExpectedTypoLinkConfiguration(array $expected, array $mconf, array $page, string $oTarget, string|int $addParams = '', string|int $typeOverride = '', int|string|null $overrideId = null): void
     {
         $expected['page'] = new Page($page);
-        $cObject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->onlyMethods(['createLink'])
-            ->getMock();
+        $cObject = $this->createMock(ContentObjectRenderer::class);
         $cObject->expects(self::once())->method('createLink')->with('|', $expected);
-        $this->subject = $this->getAccessibleMockForAbstractClass(AbstractMenuContentObject::class);
-        $this->subject->_set('parent_cObj', $cObject);
-        $this->subject->_set('mconf', $mconf);
-        $this->subject->_call('menuTypoLink', $page, $oTarget, $addParams, $typeOverride, $overrideId);
+        $subject = new AbstractMenuContentObjectFixture();
+        $subject->parent_cObj = $cObject;
+        $subject->mconf = $mconf;
+        $subject->menuTypoLink($page, $oTarget, $addParams, $typeOverride, $overrideId);
     }
 }
diff --git a/typo3/sysext/frontend/Tests/Unit/ContentObject/Menu/Fixtures/AbstractMenuContentObjectFixture.php b/typo3/sysext/frontend/Tests/Unit/ContentObject/Menu/Fixtures/AbstractMenuContentObjectFixture.php
new file mode 100644
index 0000000000000000000000000000000000000000..4b8638246578efc9d4218930c4ae9cf23dd3ae59
--- /dev/null
+++ b/typo3/sysext/frontend/Tests/Unit/ContentObject/Menu/Fixtures/AbstractMenuContentObjectFixture.php
@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+namespace TYPO3\CMS\Frontend\Tests\Unit\ContentObject\Menu\Fixtures;
+
+use Psr\Http\Message\ServerRequestInterface;
+use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
+use TYPO3\CMS\Core\Cache\Frontend\NullFrontend;
+use TYPO3\CMS\Frontend\ContentObject\Menu\AbstractMenuContentObject;
+use TYPO3\CMS\Frontend\Typolink\LinkResultInterface;
+
+final class AbstractMenuContentObjectFixture extends AbstractMenuContentObject
+{
+    public $conf = [];
+    public $mconf = [];
+    public $sys_page;
+    public $id;
+    public $menuArr;
+    public ServerRequestInterface $request;
+
+    public function isItemState($kind, $key)
+    {
+        return parent::isItemState($kind, $key);
+    }
+
+    public function menuTypoLink(array $page, string $oTarget, $addParams, $typeOverride, ?int $overridePageId = null): LinkResultInterface
+    {
+        return parent::menuTypoLink($page, $oTarget, $addParams, $typeOverride, $overridePageId);
+    }
+
+    public function sectionIndex($altSortField, $pid = null)
+    {
+        return parent::sectionIndex($altSortField, $pid);
+    }
+
+    protected function getRuntimeCache(): FrontendInterface
+    {
+        return new NullFrontend('testing');
+    }
+}
diff --git a/typo3/sysext/frontend/Tests/Unit/Typolink/AbstractTypolinkBuilderTest.php b/typo3/sysext/frontend/Tests/Unit/Typolink/AbstractTypolinkBuilderTest.php
index 67330544fca7827d9d7d4df04c4758457fc4e196..5364c69a8455581414d6ccfd8f46efa44482bacf 100644
--- a/typo3/sysext/frontend/Tests/Unit/Typolink/AbstractTypolinkBuilderTest.php
+++ b/typo3/sysext/frontend/Tests/Unit/Typolink/AbstractTypolinkBuilderTest.php
@@ -19,11 +19,9 @@ namespace TYPO3\CMS\Frontend\Tests\Unit\Typolink;
 
 use PHPUnit\Framework\Attributes\DataProvider;
 use PHPUnit\Framework\Attributes\Test;
-use PHPUnit\Framework\MockObject\MockObject;
 use Psr\EventDispatcher\EventDispatcherInterface;
 use Psr\Log\LoggerInterface;
 use Symfony\Component\DependencyInjection\Container;
-use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\EventDispatcher\NoopEventDispatcher;
 use TYPO3\CMS\Core\Http\ServerRequest;
 use TYPO3\CMS\Core\Log\LogManager;
@@ -31,46 +29,23 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Utility\StringUtility;
 use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
-use TYPO3\CMS\Frontend\Typolink\AbstractTypolinkBuilder;
+use TYPO3\CMS\Frontend\Tests\Unit\Typolink\Fixtures\AbstractTypolinkBuilderFixture;
 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
 
 final class AbstractTypolinkBuilderTest extends UnitTestCase
 {
     protected bool $resetSingletonInstances = true;
-
     protected bool $backupEnvironment = true;
 
-    protected TypoScriptFrontendController&MockObject $frontendControllerMock;
-
     protected function setUp(): void
     {
         parent::setUp();
-        $this->createMockedLoggerAndLogManager();
-        $this->frontendControllerMock = $this
-            ->getMockBuilder(TypoScriptFrontendController::class)
-            ->disableOriginalConstructor()
-            ->getMock();
-    }
-
-    //////////////////////
-    // Utility functions
-    //////////////////////
-    /**
-     * Avoid logging to the file system (file writer is currently the only configured writer)
-     */
-    protected function createMockedLoggerAndLogManager(): void
-    {
         $logManagerMock = $this->getMockBuilder(LogManager::class)->getMock();
         $loggerMock = $this->getMockBuilder(LoggerInterface::class)->getMock();
-        $logManagerMock
-            ->method('getLogger')
-            ->willReturn($loggerMock);
+        $logManagerMock->method('getLogger')->willReturn($loggerMock);
         GeneralUtility::setSingletonInstance(LogManager::class, $logManagerMock);
     }
 
-    /**
-     * @return array The test data for forceAbsoluteUrlReturnsAbsoluteUrl
-     */
     public static function forceAbsoluteUrlReturnsCorrectAbsoluteUrlDataProvider(): array
     {
         return [
@@ -164,28 +139,13 @@ final class AbstractTypolinkBuilderTest extends UnitTestCase
         ];
     }
 
-    /**
-     * @param string $expected The expected URL
-     * @param string $url The URL to parse and manipulate
-     * @param array $configuration The configuration array
-     */
     #[DataProvider('forceAbsoluteUrlReturnsCorrectAbsoluteUrlDataProvider')]
     #[Test]
     public function forceAbsoluteUrlReturnsCorrectAbsoluteUrl(string $expected, string $url, array $configuration): void
     {
-        Environment::initialize(
-            Environment::getContext(),
-            true,
-            false,
-            Environment::getProjectPath(),
-            Environment::getPublicPath(),
-            Environment::getVarPath(),
-            Environment::getConfigPath(),
-            Environment::getPublicPath() . '/index.php',
-            Environment::isWindows() ? 'WINDOWS' : 'UNIX'
-        );
-        $this->frontendControllerMock->absRefPrefix = '';
-        $cObj = new ContentObjectRenderer($this->frontendControllerMock, new Container());
+        $frontendControllerMock = $this->createMock(TypoScriptFrontendController::class);
+        $frontendControllerMock->absRefPrefix = '';
+        $cObj = new ContentObjectRenderer($frontendControllerMock, new Container());
         // Force hostname
         $serverRequest = new ServerRequest(
             'http://localhost/index.php',
@@ -195,31 +155,15 @@ final class AbstractTypolinkBuilderTest extends UnitTestCase
             ['HTTP_HOST' => 'localhost', 'SCRIPT_NAME' => '/index.php']
         );
         $cObj->setRequest($serverRequest);
-        $subject = $this->getAccessibleMock(
-            AbstractTypolinkBuilder::class,
-            ['build'],
-            [$cObj, $this->frontendControllerMock]
-        );
-
-        self::assertEquals($expected, $subject->_call('forceAbsoluteUrl', $url, $configuration));
+        $subject = new AbstractTypolinkBuilderFixture($cObj, $frontendControllerMock);
+        self::assertEquals($expected, $subject->forceAbsoluteUrl($url, $configuration));
     }
 
     #[Test]
     public function forceAbsoluteUrlReturnsCorrectAbsoluteUrlWithSubfolder(): void
     {
-        Environment::initialize(
-            Environment::getContext(),
-            true,
-            false,
-            Environment::getProjectPath(),
-            Environment::getPublicPath(),
-            Environment::getVarPath(),
-            Environment::getConfigPath(),
-            Environment::getPublicPath() . '/index.php',
-            Environment::isWindows() ? 'WINDOWS' : 'UNIX'
-        );
-        $cObj = new ContentObjectRenderer($this->frontendControllerMock, new Container());
-
+        $frontendControllerMock = $this->createMock(TypoScriptFrontendController::class);
+        $cObj = new ContentObjectRenderer($frontendControllerMock, new Container());
         // Force hostname
         $serverRequest = new ServerRequest(
             'http://localhost/subfolder/index.php',
@@ -229,26 +173,15 @@ final class AbstractTypolinkBuilderTest extends UnitTestCase
             ['HTTP_HOST' => 'localhost', 'SCRIPT_NAME' => '/subfolder/index.php']
         );
         $cObj->setRequest($serverRequest);
-        $subject = $this->getAccessibleMock(
-            AbstractTypolinkBuilder::class,
-            ['build'],
-            [$cObj, $this->frontendControllerMock]
-        );
-
+        $subject = new AbstractTypolinkBuilderFixture($cObj, $frontendControllerMock);
         $expected = 'http://localhost/subfolder/fileadmin/my.pdf';
         $url = 'fileadmin/my.pdf';
         $configuration = [
             'forceAbsoluteUrl' => '1',
         ];
-
-        self::assertEquals($expected, $subject->_call('forceAbsoluteUrl', $url, $configuration));
+        self::assertEquals($expected, $subject->forceAbsoluteUrl($url, $configuration));
     }
 
-    /**
-     * Data provider for resolveTargetAttribute
-     *
-     * @return array [[$expected, $conf, $name],]
-     */
     public static function resolveTargetAttributeDataProvider(): array
     {
         $targetName = StringUtility::getUniqueId('name_');
@@ -256,23 +189,23 @@ final class AbstractTypolinkBuilderTest extends UnitTestCase
         return [
             'Take target from $conf, if $conf[$targetName] is set.' =>
                 [
-                    $target,
-                    [$targetName => $target], // $targetName is set
-                    $targetName,
+                    'expected' => $target,
+                    'conf' => [$targetName => $target], // $targetName is set
+                    'name' => $targetName,
                 ],
             ' If all hopes fail, an empty string is returned. ' =>
                 [
-                    '',
-                    [],
-                    $targetName,
+                    'expected' => '',
+                    'conf' => [],
+                    'name' => $targetName,
                 ],
             'It finally applies stdWrap' =>
                 [
-                    'wrap_target',
-                    [$targetName . '.' =>
+                    'expected' => 'wrap_target',
+                    'conf' => [$targetName . '.' =>
                         [ 'ifEmpty' => 'wrap_target' ],
                     ],
-                    $targetName,
+                    'name' => $targetName,
                 ],
         ];
     }
@@ -284,7 +217,8 @@ final class AbstractTypolinkBuilderTest extends UnitTestCase
         array $conf,
         string $name,
     ): void {
-        $cObj = new ContentObjectRenderer($this->frontendControllerMock, new Container());
+        $frontendControllerMock = $this->createMock(TypoScriptFrontendController::class);
+        $cObj = new ContentObjectRenderer($frontendControllerMock, new Container());
         $serverRequest = new ServerRequest(
             'http://localhost/subfolder/index.php',
             'GET',
@@ -296,12 +230,7 @@ final class AbstractTypolinkBuilderTest extends UnitTestCase
         $container = new Container();
         $container->set(EventDispatcherInterface::class, new NoopEventDispatcher());
         GeneralUtility::setContainer($container);
-        $subject = $this->getAccessibleMockForAbstractClass(AbstractTypolinkBuilder::class, [$cObj, $this->frontendControllerMock]);
-        $actual = $subject->_call(
-            'resolveTargetAttribute',
-            $conf,
-            $name,
-        );
-        self::assertEquals($expected, $actual);
+        $subject = new AbstractTypolinkBuilderFixture($cObj, $frontendControllerMock);
+        self::assertEquals($expected, $subject->resolveTargetAttribute($conf, $name));
     }
 }
diff --git a/typo3/sysext/frontend/Tests/Unit/Typolink/Fixtures/AbstractTypolinkBuilderFixture.php b/typo3/sysext/frontend/Tests/Unit/Typolink/Fixtures/AbstractTypolinkBuilderFixture.php
new file mode 100644
index 0000000000000000000000000000000000000000..4f168a5223e2b2ac6ced66793293caca1e259645
--- /dev/null
+++ b/typo3/sysext/frontend/Tests/Unit/Typolink/Fixtures/AbstractTypolinkBuilderFixture.php
@@ -0,0 +1,40 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+namespace TYPO3\CMS\Frontend\Tests\Unit\Typolink\Fixtures;
+
+use TYPO3\CMS\Frontend\Typolink\AbstractTypolinkBuilder;
+use TYPO3\CMS\Frontend\Typolink\LinkResult;
+use TYPO3\CMS\Frontend\Typolink\LinkResultInterface;
+
+final class AbstractTypolinkBuilderFixture extends AbstractTypolinkBuilder
+{
+    public function build(array &$linkDetails, string $linkText, string $target, array $conf): LinkResultInterface
+    {
+        return new LinkResult('type', 'url');
+    }
+
+    public function forceAbsoluteUrl(string $url, array $configuration): string
+    {
+        return parent::forceAbsoluteUrl($url, $configuration);
+    }
+
+    public function resolveTargetAttribute(array $conf, string $name): string
+    {
+        return parent::resolveTargetAttribute($conf, $name);
+    }
+}
diff --git a/typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/AbstractCoreMatcherTest.php b/typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/AbstractCoreMatcherTest.php
index fbab6f0a1ee8dff4099255eec244319aa355bafb..fe82ddaafa2aa88f25e065a63a815d476ad9686e 100644
--- a/typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/AbstractCoreMatcherTest.php
+++ b/typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/AbstractCoreMatcherTest.php
@@ -18,7 +18,7 @@ declare(strict_types=1);
 namespace TYPO3\CMS\Install\Tests\Unit\ExtensionScanner\Php\Matcher;
 
 use PHPUnit\Framework\Attributes\Test;
-use TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\AbstractCoreMatcher;
+use TYPO3\CMS\Install\Tests\Unit\ExtensionScanner\Php\Matcher\Fixtures\AbstractCoreMatcherFixture;
 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
 
 final class AbstractCoreMatcherTest extends UnitTestCase
@@ -26,7 +26,7 @@ final class AbstractCoreMatcherTest extends UnitTestCase
     #[Test]
     public function validateMatcherDefinitionsRunsFineWithProperDefinition(): void
     {
-        $matcher = $this->getAccessibleMockForAbstractClass(AbstractCoreMatcher::class, [], '', false);
+        $subject = new AbstractCoreMatcherFixture();
         $configuration = [
             'foo/bar->baz' => [
                 'requiredArg1' => 42,
@@ -35,14 +35,14 @@ final class AbstractCoreMatcherTest extends UnitTestCase
                 ],
             ],
         ];
-        $matcher->_set('matcherDefinitions', $configuration);
-        $matcher->_call('validateMatcherDefinitions', ['requiredArg1']);
+        $subject->matcherDefinitions = $configuration;
+        $subject->validateMatcherDefinitions(['requiredArg1']);
     }
 
     #[Test]
     public function validateMatcherDefinitionsThrowsIfRequiredArgIsNotInConfig(): void
     {
-        $matcher = $this->getAccessibleMockForAbstractClass(AbstractCoreMatcher::class, [], '', false);
+        $subject = new AbstractCoreMatcherFixture();
         $configuration = [
             'foo/bar->baz' => [
                 'someNotRequiredConfig' => '',
@@ -51,31 +51,31 @@ final class AbstractCoreMatcherTest extends UnitTestCase
                 ],
             ],
         ];
-        $matcher->_set('matcherDefinitions', $configuration);
+        $subject->matcherDefinitions = $configuration;
         $this->expectException(\InvalidArgumentException::class);
         $this->expectExceptionCode(1500492001);
-        $matcher->_call('validateMatcherDefinitions', ['requiredArg1']);
+        $subject->validateMatcherDefinitions(['requiredArg1']);
     }
 
     #[Test]
     public function validateMatcherDefinitionsThrowsWithMissingRestFiles(): void
     {
-        $matcher = $this->getAccessibleMockForAbstractClass(AbstractCoreMatcher::class, [], '', false);
+        $subject = new AbstractCoreMatcherFixture();
         $configuration = [
             'foo/bar->baz' => [
                 'restFiles' => [],
             ],
         ];
-        $matcher->_set('matcherDefinitions', $configuration);
+        $subject->matcherDefinitions = $configuration;
         $this->expectException(\InvalidArgumentException::class);
         $this->expectExceptionCode(1500496068);
-        $matcher->_call('validateMatcherDefinitions', []);
+        $subject->validateMatcherDefinitions([]);
     }
 
     #[Test]
     public function validateMatcherDefinitionsThrowsWithEmptySingleRestFile(): void
     {
-        $matcher = $this->getAccessibleMockForAbstractClass(AbstractCoreMatcher::class, [], '', false);
+        $subject = new AbstractCoreMatcherFixture();
         $configuration = [
             'foo/bar->baz' => [
                 'restFiles' => [
@@ -84,24 +84,24 @@ final class AbstractCoreMatcherTest extends UnitTestCase
                 ],
             ],
         ];
-        $matcher->_set('matcherDefinitions', $configuration);
+        $subject->matcherDefinitions = $configuration;
         $this->expectException(\InvalidArgumentException::class);
         $this->expectExceptionCode(1500735983);
-        $matcher->_call('validateMatcherDefinitions', []);
+        $subject->validateMatcherDefinitions([]);
     }
 
     #[Test]
     public function initializeMethodNameArrayThrowsWithInvalidKeys(): void
     {
-        $matcher = $this->getAccessibleMockForAbstractClass(AbstractCoreMatcher::class, [], '', false);
+        $subject = new AbstractCoreMatcherFixture();
         $configuration = [
             'no\method\given' => [
                 'restFiles' => [],
             ],
         ];
-        $matcher->_set('matcherDefinitions', $configuration);
+        $subject->matcherDefinitions = $configuration;
         $this->expectException(\RuntimeException::class);
         $this->expectExceptionCode(1500557309);
-        $matcher->_call('initializeFlatMatcherDefinitions');
+        $subject->initializeFlatMatcherDefinitions();
     }
 }
diff --git a/typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/Fixtures/AbstractCoreMatcherFixture.php b/typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/Fixtures/AbstractCoreMatcherFixture.php
new file mode 100644
index 0000000000000000000000000000000000000000..d5a597b0331975e7915f789e4b7ddeaef82f46e2
--- /dev/null
+++ b/typo3/sysext/install/Tests/Unit/ExtensionScanner/Php/Matcher/Fixtures/AbstractCoreMatcherFixture.php
@@ -0,0 +1,35 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+namespace TYPO3\CMS\Install\Tests\Unit\ExtensionScanner\Php\Matcher\Fixtures;
+
+use TYPO3\CMS\Install\ExtensionScanner\Php\Matcher\AbstractCoreMatcher;
+
+final class AbstractCoreMatcherFixture extends AbstractCoreMatcher
+{
+    public $matcherDefinitions = [];
+
+    public function initializeFlatMatcherDefinitions()
+    {
+        parent::initializeFlatMatcherDefinitions();
+    }
+
+    public function validateMatcherDefinitions(array $requiredArrayKeys = [])
+    {
+        parent::validateMatcherDefinitions($requiredArrayKeys);
+    }
+}