├── .gitignore ├── Code ├── Generator.php └── Generator │ ├── ClassNameParser.php │ ├── UnitTest.php │ └── UnitTest │ ├── ConstructorArgumentsResolver.php │ ├── SetupMethodBuilder.php │ └── TestObjectCreationBuilder.php ├── Console └── Command │ └── Generate.php ├── LICENSE ├── README.md ├── Test └── Unit │ └── Code │ └── Generator │ ├── ClassNameParserTest.php │ └── UnitTest │ ├── ConstructorArgumentsResolverTest.php │ ├── SetupMethodBuilderTest.php │ └── TestObjectCreationBuilderTest.php ├── composer.json ├── etc ├── di.xml └── module.xml └── registration.php /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea -------------------------------------------------------------------------------- /Code/Generator.php: -------------------------------------------------------------------------------- 1 | testGeneratorFactory = $testGenerator; 46 | $this->ioObject = $ioObject; 47 | $this->reader = $reader; 48 | $this->classNameParser = $classNameParser; 49 | } 50 | 51 | /** 52 | * @param string $path 53 | * 54 | * @return bool 55 | */ 56 | public function process(string $path) 57 | { 58 | $sourceClass = $this->getClassName($path); 59 | if (!\class_exists($sourceClass)) { 60 | return null; 61 | } 62 | 63 | $resultClass = \explode('\\', trim($sourceClass, '\\')); 64 | \array_splice($resultClass, 2, 0, 'Test\\Unit'); 65 | $resultClass = \implode('\\', $resultClass) . 'Test'; 66 | if (\class_exists($resultClass)) { 67 | return null; 68 | } 69 | $generator = $this->testGeneratorFactory->create([ 70 | 'sourceClassName' => $sourceClass, 71 | 'resultClassName' => $resultClass, 72 | 'ioObject' => $this->ioObject, 73 | ]); 74 | 75 | return $generator->generate(); 76 | } 77 | 78 | /** 79 | * @param string $path 80 | * 81 | * @return string 82 | * @throws \Magento\Framework\Exception\FileSystemException 83 | */ 84 | private function getClassName(string $path): string 85 | { 86 | if (\class_exists($path)) { 87 | return $path; 88 | } 89 | 90 | $fileContents = $this->reader->fileGetContents($path); 91 | return $this->classNameParser->parseClassName($fileContents); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Code/Generator/ClassNameParser.php: -------------------------------------------------------------------------------- 1 | 8.0, T_STRING as fallback 24 | $qualifiedNameToken = defined('T_NAME_QUALIFIED') ? T_NAME_QUALIFIED : T_STRING; 25 | if ($tokens[$j][0] === $qualifiedNameToken) { 26 | $namespace .= '\\' . $tokens[$j][1]; 27 | } else { 28 | if ($tokens[$j] === '{' || $tokens[$j] === ';') { 29 | break; 30 | } 31 | } 32 | } 33 | } 34 | if ($tokens[$i][0] === T_CLASS) { 35 | for ($j = $i + 1; $j < $tokensCount; $j++) { 36 | if ($tokens[$j] === '{') { 37 | $class = '\\' . $tokens[$i + 2][1]; 38 | break 2; 39 | } 40 | } 41 | } 42 | } 43 | return $namespace . $class; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Code/Generator/UnitTest.php: -------------------------------------------------------------------------------- 1 | constructorArgumentsResolver = $constructorArgumentsResolver; 52 | $this->setupMethodBuilder = $setupMethodBuilder; 53 | $this->testObjectCreationBuilder = $testObjectCreationBuilder; 54 | parent::__construct($sourceClassName, $resultClassName, $ioObject, $classGenerator, $definedClasses); 55 | } 56 | 57 | /** 58 | * @return \ReflectionClass 59 | * @throws \ReflectionException 60 | */ 61 | private function getSourceReflectionClass(): \ReflectionClass 62 | { 63 | if ($this->sourceReflectionClass === null) { 64 | $this->sourceReflectionClass = new \ReflectionClass($this->getSourceClassName()); 65 | } 66 | return $this->sourceReflectionClass; 67 | } 68 | 69 | /** 70 | * @return array 71 | */ 72 | protected function _getClassDocBlock() 73 | { 74 | $description = '@covers ' . $this->getSourceClassName(); 75 | return ['shortDescription' => $description]; 76 | } 77 | 78 | /** 79 | * Retrieve class properties 80 | * 81 | * @return array 82 | */ 83 | protected function _getClassProperties() 84 | { 85 | $properties = array_map(function($e) { 86 | return [ 87 | 'name' => $e['name'], 88 | 'visibility' => 'private', 89 | 'docblock' => [ 90 | 'shortDescription' => "Mock {$e['name']}", 91 | 'tags' => [['name' => 'var', 'description' => '\\' . "{$e['class']}|" . \PHPUnit\Framework\MockObject\MockObject::class]], 92 | ], 93 | ]; 94 | }, $this->getConstructorArgumentsWithFactoryInstances($this->getConstructorArguments())); 95 | 96 | $properties[] = [ 97 | 'name' => 'objectManager', 98 | 'visibility' => 'private', 99 | 'docblock' => [ 100 | 'shortDescription' => 'Object Manager instance', 101 | 'tags' => [['name' => 'var', 'description' => '\\' . \Magento\Framework\ObjectManagerInterface::class]], 102 | ], 103 | ]; 104 | 105 | $properties[] = [ 106 | 'name' => 'testObject', 107 | 'visibility' => 'private', 108 | 'docblock' => [ 109 | 'shortDescription' => 'Object to test', 110 | 'tags' => [['name' => 'var', 'description' => $this->getSourceClassName()]], 111 | ], 112 | ]; 113 | 114 | return $properties; 115 | } 116 | 117 | /** 118 | * Get default constructor definition for generated class 119 | * 120 | * @return array 121 | */ 122 | protected function _getDefaultConstructorDefinition() 123 | { 124 | return []; 125 | } 126 | 127 | /** 128 | * Returns list of methods for class generator 129 | * 130 | * @return array 131 | */ 132 | protected function _getClassMethods() 133 | { 134 | $setupMethodParamsDefinition = $this->getSetupMethodParamsDefinition( 135 | $this->getConstructorArgumentsWithFactoryInstances( 136 | $this->getConstructorArguments() 137 | ) 138 | ); 139 | $testObjectCreationCode = $this->testObjectCreationBuilder->build( 140 | $this->getSourceClassName(), 141 | $this->getObjectCreationParams($this->getConstructorArguments()) 142 | ); 143 | $setUp = $this->setupMethodBuilder->build($setupMethodParamsDefinition, $testObjectCreationCode); 144 | 145 | return \array_merge([$setUp], $this->getTestMethodsWithProviders()); 146 | } 147 | 148 | /** 149 | * @return string 150 | */ 151 | protected function _generateCode() 152 | { 153 | $this->addDefaultUses(); 154 | $this->addExtends(); 155 | 156 | return parent::_generateCode(); 157 | } 158 | 159 | /** 160 | * @param array $arguments 161 | * 162 | * @return array 163 | */ 164 | private function getSetupMethodParamsDefinition(array $arguments): array 165 | { 166 | $result = []; 167 | foreach ($arguments as $argument) { 168 | $result[] = "\$this->{$argument['name']}" 169 | . " = \$this->createMock(\\" . "{$argument['class']}::class);"; 170 | if (\preg_match('/\w+Factory$/', $argument['class']) === 1) { 171 | $instanceName = $argument['name'] . 'Instance'; 172 | $result[] = "\$this->{$argument['name']}" 173 | . "->method('create')" 174 | . "->willReturn(\$this->$instanceName);"; 175 | } 176 | } 177 | return $result; 178 | } 179 | 180 | /** 181 | * @param string $sourceClassName 182 | * @param array $objectCreationParams 183 | * 184 | * @return string 185 | */ 186 | private function getTestObjectCreation( 187 | string $sourceClassName, 188 | array $objectCreationParams 189 | ): string { 190 | return "\$this->testObject = \$this->objectManager->getObject(\n" 191 | . $sourceClassName . "::class,\n" 192 | . " [\n" 193 | . \implode("\n", $objectCreationParams) 194 | . "\n ]\n" 195 | . ");"; 196 | } 197 | 198 | /** 199 | * @param array $constructorArguments 200 | * 201 | * @return array 202 | */ 203 | private function getObjectCreationParams(array $constructorArguments): array 204 | { 205 | return \array_map(function ($e) { 206 | return " '{$e['name']}' => \$this->{$e['name']},"; 207 | }, $constructorArguments); 208 | } 209 | 210 | /** 211 | * @return array 212 | */ 213 | private function getConstructorArguments(): array 214 | { 215 | if ($this->constructorArguments === null) { 216 | try { 217 | $constructor = $this->getSourceReflectionClass()->getMethod('__construct'); 218 | $this->constructorArguments = $this->constructorArgumentsResolver->resolve($constructor); 219 | } catch (\ReflectionException $e) { 220 | $this->constructorArguments = []; 221 | } 222 | } 223 | 224 | return $this->constructorArguments; 225 | } 226 | 227 | /** 228 | * @param array $arguments 229 | * 230 | * @return array 231 | */ 232 | private function getConstructorArgumentsWithFactoryInstances(array $arguments): array 233 | { 234 | $result = []; 235 | foreach ($arguments as $argument) { 236 | if (\preg_match('/\w+Factory$/', $argument['class']) === 1) { 237 | $result[] = [ 238 | 'name' => $argument['name'] . 'Instance', 239 | 'class' => \substr($argument['class'], 0, -7) 240 | ]; 241 | } 242 | $result[] = $argument; 243 | } 244 | return $result; 245 | } 246 | 247 | /** 248 | * @return array 249 | */ 250 | private function getTestMethodsWithProviders(): array 251 | { 252 | $methods = []; 253 | try { 254 | $publicMethods = $this->getSourceReflectionClass()->getMethods(\ReflectionMethod::IS_PUBLIC); 255 | foreach ($publicMethods as $method) { 256 | if (!($method->isConstructor() || $method->isFinal() || $method->isStatic() || $method->isDestructor()) 257 | && !in_array($method->getName(), ['__sleep', '__wakeup', '__clone']) 258 | ) { 259 | $methods[] = $this->getDataProvider($method); 260 | $methods[] = $this->getTestMethod($method); 261 | } 262 | } 263 | } catch (\ReflectionException $e) { 264 | return $methods; 265 | } 266 | 267 | return $methods; 268 | } 269 | 270 | /** 271 | * Retrieve method info 272 | * 273 | * @param \ReflectionMethod $method 274 | * @return array 275 | */ 276 | private function getTestMethod(\ReflectionMethod $method) 277 | { 278 | $testMethodName = 'test' . \ucfirst($method->getName()); 279 | $methodInfo = [ 280 | 'name' => $testMethodName, 281 | 'parameters' => [ 282 | [ 283 | 'name' => 'prerequisites', 284 | 'type' => 'array', 285 | ], 286 | [ 287 | 'name' => 'expectedResult', 288 | 'type' => 'array', 289 | ], 290 | ], 291 | 'body' => "\$this->assertEquals(\$expectedResult['param'], \$prerequisites['param']);", 292 | 'docblock' => [ 293 | 'tags' => [['name' => 'dataProvider', 'description' => 'dataProviderFor' . \ucfirst($testMethodName)]], 294 | ], 295 | ]; 296 | 297 | return $methodInfo; 298 | } 299 | 300 | /** 301 | * Retrieve method info 302 | * 303 | * @param \ReflectionMethod $method 304 | * @return array 305 | */ 306 | private function getDataProvider(\ReflectionMethod $method): array 307 | { 308 | $testMethodName = 'test' . \ucfirst($method->getName()); 309 | $methodInfo = [ 310 | 'name' => 'dataProviderFor' . \ucfirst($testMethodName), 311 | 'body' => $this->getDataProviderBody(), 312 | 'docblock' => [ 313 | 'tags' => [['name' => 'return', 'description' => 'array']], 314 | ], 315 | ]; 316 | 317 | return $methodInfo; 318 | } 319 | 320 | /** 321 | * @return string 322 | */ 323 | private function getDataProviderBody(): string 324 | { 325 | return << [ 328 | 'prerequisites' => ['param' => 1], 329 | 'expectedResult' => ['param' => 1] 330 | ] 331 | ]; 332 | BODY; 333 | } 334 | 335 | /** 336 | * add uses, which are needed for unit testing 337 | */ 338 | private function addDefaultUses() 339 | { 340 | $this->_classGenerator->addUse( 341 | \Magento\Framework\TestFramework\Unit\Helper\ObjectManager::class 342 | ); 343 | $this->_classGenerator->addUse( 344 | \PHPUnit\Framework\TestCase::class 345 | ); 346 | $this->_classGenerator->addUse( 347 | \PHPUnit\Framework\MockObject\MockObject::class 348 | ); 349 | } 350 | 351 | /** 352 | * add extends from testcase class 353 | */ 354 | private function addExtends() 355 | { 356 | $this->_classGenerator->setExtendedClass(\PHPUnit\Framework\TestCase::class); 357 | } 358 | 359 | /** 360 | * @param string $sourceCode 361 | * 362 | * @return string 363 | */ 364 | protected function _fixCodeStyle($sourceCode) 365 | { 366 | $sourceCode = parent::_fixCodeStyle($sourceCode); 367 | $sourceCode = preg_replace('/(\sprivate\s\$\w+)\s\=\snull\;/', '$1;', $sourceCode); 368 | return $sourceCode; 369 | } 370 | } 371 | -------------------------------------------------------------------------------- /Code/Generator/UnitTest/ConstructorArgumentsResolver.php: -------------------------------------------------------------------------------- 1 | getParameters() as $parameter) { 20 | if (!$parameter->getType()) { 21 | continue; 22 | } 23 | $constructorArguments[] = [ 24 | 'name' => $parameter->getName(), 25 | 'class' => $parameter->getType()->getName() 26 | ]; 27 | } 28 | } catch (\ReflectionException $e) { 29 | return $constructorArguments; 30 | } 31 | 32 | return $constructorArguments; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Code/Generator/UnitTest/SetupMethodBuilder.php: -------------------------------------------------------------------------------- 1 | 'setUp', 19 | 'parameters' => [], 20 | 'body' => "\$this->objectManager = new ObjectManager(\$this);\n" 21 | . \implode("\n", $setupMethodParamsDefinition) . "\n" 22 | . $testObjectCreationCode, 23 | 'docblock' => [ 24 | 'shortDescription' => 'Main set up method', 25 | ], 26 | 'returnType' => 'void' 27 | ]; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Code/Generator/UnitTest/TestObjectCreationBuilder.php: -------------------------------------------------------------------------------- 1 | testObject = \$this->objectManager->getObject(\n" 20 | . $sourceClassName . "::class,\n" 21 | . " [\n" 22 | . \implode("\n", $objectCreationParams) 23 | . "\n ]\n" 24 | . ");"; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Console/Command/Generate.php: -------------------------------------------------------------------------------- 1 | objectManagerFactory = $objectManagerFactory; 52 | } 53 | 54 | /** 55 | * @inheritdoc 56 | */ 57 | protected function configure() 58 | { 59 | $this->setName(self::CONSOLE_COMMAND_NAME) 60 | ->setDescription('Generate unit test structure for defined class'); 61 | 62 | $this->addArgument( 63 | self::ARGUMENT_PATH, 64 | InputArgument::REQUIRED, 65 | 'Class name or path to file to generate unit tests for' 66 | ); 67 | } 68 | 69 | /** 70 | * @param InputInterface $input 71 | * @param OutputInterface $output 72 | * 73 | * @return int|null 74 | */ 75 | protected function execute(InputInterface $input, OutputInterface $output) 76 | { 77 | try { 78 | $path = $input->getArgument(static::ARGUMENT_PATH); 79 | $result = $this->getModel()->process($path); 80 | if ($result) { 81 | $output->writeln('Unit tests generated'); 82 | $output->writeln("$result"); 83 | } else { 84 | $output->writeln('No tests to generate'); 85 | } 86 | } catch (\Exception $e) { 87 | $output->writeln('' . $e->getMessage() . ''); 88 | 89 | return Cli::RETURN_FAILURE; 90 | } 91 | 92 | return Cli::RETURN_SUCCESS; 93 | } 94 | 95 | /** 96 | * @return Generator 97 | * @throws \Magento\Framework\Exception\LocalizedException 98 | */ 99 | private function getModel() 100 | { 101 | if (!isset($this->model)) { 102 | $this->model = $this->getObjectManager()->get(Generator::class); 103 | } 104 | 105 | return $this->model; 106 | } 107 | 108 | /** 109 | * @return ObjectManagerInterface 110 | * @throws \Magento\Framework\Exception\LocalizedException 111 | */ 112 | private function getObjectManager() 113 | { 114 | if (null == $this->objectManager) { 115 | $area = FrontNameResolver::AREA_CODE; 116 | $params = $_SERVER; 117 | $params[StoreManager::PARAM_RUN_CODE] = 'admin'; 118 | $params[StoreManager::PARAM_RUN_TYPE] = 'store'; 119 | $this->objectManager = $this->objectManagerFactory->create($params); 120 | /** @var AppState $appState */ 121 | $appState = $this->objectManager->get(AppState::class); 122 | $appState->setAreaCode($area); 123 | $configLoader = $this->objectManager->get(ConfigLoaderInterface::class); 124 | $this->objectManager->configure($configLoader->load($area)); 125 | /** @var AreaList $areaList */ 126 | $areaList = $this->objectManager->get(AreaList::class); 127 | /** @var Area $area */ 128 | $area = $areaList->getArea($appState->getAreaCode()); 129 | $area->load(Area::PART_TRANSLATE); 130 | } 131 | 132 | return $this->objectManager; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Igor Tripolskiy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Magento 2 module unit tests generator 2 | Sometimes writing new unit test for class with multiple dependencies may be tedious, so this package is intended to simplify magento2 unit tests creation. Command reads source file and generates basic unit test structure for specified class. If unit test already exists - nothing will happen. Test class is placed into test object class' module under app/code/Vendor/Module/Test/Unit/... 3 | 4 | ### How to install 5 | 6 | ```bash 7 | composer require olmer/magento-unit-tests-generator --dev 8 | php bin/magento cache:clean 9 | php bin/magento setup:di:compile 10 | ``` 11 | 12 | ### How to generate a unit test for a specific class 13 | 14 | ```bash 15 | php bin/magento dev:tests:generate-unit /app/code/Vendor/Module/path/to/file.php 16 | ``` 17 | 18 | ### Examples 19 | 20 | Source class 21 | ```php 22 | orderRepo = $orderRepository; 39 | $this->searchCriteriaFactory = $criteria; 40 | $this->filterGroupFactory = $filterGroup; 41 | $this->filterFactory = $filter; 42 | $this->orderFactory = $orderFactory; 43 | $this->sortOrderFactory = $sortOrderFactory; 44 | } 45 | 46 | public function getFilename() 47 | { 48 | ... 49 | } 50 | 51 | public function getLastShippedOrder() 52 | { 53 | ... 54 | } 55 | } 56 | 57 | ``` 58 | Generated test class 59 | ```php 60 | objectManager = new ObjectManager($this); 141 | $this->context = $this->createMock(\Magento\Framework\App\Helper\Context::class); 142 | $this->orderRepository = $this->createMock(\Magento\Sales\Api\OrderRepositoryInterface::class); 143 | $this->criteria = $this->createMock(\Magento\Framework\Api\SearchCriteriaFactory::class); 144 | $this->filterGroup = $this->createMock(\Magento\Framework\Api\Search\FilterGroupFactory::class); 145 | $this->filter = $this->createMock(\Magento\Framework\Api\FilterFactory::class); 146 | $this->orderFactory = $this->createMock(\Magento\Sales\Model\OrderFactory::class); 147 | $this->sortOrderFactory = $this->createMock(\Magento\Framework\Api\SortOrderFactory::class); 148 | $this->testObject = $this->objectManager->getObject( 149 | \Vendor\Reorder\Helper\Reorder::class, 150 | [ 151 | 'context' => $this->context, 152 | 'orderRepository' => $this->orderRepository, 153 | 'criteria' => $this->criteria, 154 | 'filterGroup' => $this->filterGroup, 155 | 'filter' => $this->filter, 156 | 'orderFactory' => $this->orderFactory, 157 | 'sortOrderFactory' => $this->sortOrderFactory, 158 | ] 159 | ); 160 | } 161 | 162 | /** 163 | * @return array 164 | */ 165 | public function dataProviderForTestGetLastShippedOrder() 166 | { 167 | return [ 168 | 'Testcase 1' => [ 169 | 'prerequisites' => ['param' => 1], 170 | 'expectedResult' => ['param' => 1] 171 | ] 172 | ]; 173 | } 174 | 175 | /** 176 | * @dataProvider dataProviderForTestGetLastShippedOrder 177 | */ 178 | public function testGetLastShippedOrder(array $prerequisites, array $expectedResult) 179 | { 180 | $this->assertEquals($expectedResult['param'], $prerequisites['param']); 181 | } 182 | 183 | /** 184 | * @return array 185 | */ 186 | public function dataProviderForTestIsModuleOutputEnabled() 187 | { 188 | return [ 189 | 'Testcase 1' => [ 190 | 'prerequisites' => ['param' => 1], 191 | 'expectedResult' => ['param' => 1] 192 | ] 193 | ]; 194 | } 195 | 196 | /** 197 | * @dataProvider dataProviderForTestIsModuleOutputEnabled 198 | */ 199 | public function testIsModuleOutputEnabled(array $prerequisites, array $expectedResult) 200 | { 201 | $this->assertEquals($expectedResult['param'], $prerequisites['param']); 202 | } 203 | } 204 | ``` 205 | -------------------------------------------------------------------------------- /Test/Unit/Code/Generator/ClassNameParserTest.php: -------------------------------------------------------------------------------- 1 | objectManager = new ObjectManager($this); 32 | 33 | $this->testObject = $this->objectManager->getObject( 34 | \Olmer\UnitTestsGenerator\Code\Generator\ClassNameParser::class 35 | ); 36 | } 37 | 38 | /** 39 | * @return array 40 | */ 41 | public function dataProviderForTestParseClassName() 42 | { 43 | return [ 44 | 'basic Magento class' => [ 45 | 'content' => ' '\Olmer\UnitTestsGenerator\Code\Generator\ClassNameParser' 47 | ] 48 | ]; 49 | } 50 | 51 | /** 52 | * @dataProvider dataProviderForTestParseClassName 53 | * 54 | * @param string $content 55 | * @param string $expected 56 | * 57 | * @return void 58 | */ 59 | public function testParseClassName(string $content, string $expected) 60 | { 61 | $result = $this->testObject->parseClassName($content); 62 | $this->assertEquals($expected, $result); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Test/Unit/Code/Generator/UnitTest/ConstructorArgumentsResolverTest.php: -------------------------------------------------------------------------------- 1 | objectManager = new ObjectManager($this); 38 | 39 | $this->testObject = $this->objectManager->getObject( 40 | \Olmer\UnitTestsGenerator\Code\Generator\UnitTest\ConstructorArgumentsResolver::class, 41 | ); 42 | $this->constructor = $this->createMock(\ReflectionMethod::class); 43 | } 44 | 45 | /** 46 | * @return array 47 | */ 48 | public function dataProviderForTestResolve() 49 | { 50 | return [ 51 | 'Testcase 1' => [ 52 | 'constructorParametersData' => [ 53 | 'name1' => 'class1', 54 | 'name2' => 'class2', 55 | 'name3' => null 56 | ], 57 | 'result' => [ 58 | ['name' => 'name1', 'class' => 'class1'], 59 | ['name' => 'name2', 'class' => 'class2'] 60 | ] 61 | ] 62 | ]; 63 | } 64 | 65 | /** 66 | * @dataProvider dataProviderForTestResolve 67 | */ 68 | public function testResolve(array $constructorParametersData, array $expectedResult) 69 | { 70 | $parameters = []; 71 | foreach ($constructorParametersData as $name => $className) { 72 | $parameter = $this->createMock(\ReflectionParameter::class); 73 | $class = null; 74 | if ($className) { 75 | $class = $this->createMock(\ReflectionNamedType::class); 76 | $class->method('getName')->willReturn($className); 77 | } 78 | $parameter->method('getType')->willReturn($class); 79 | $parameter->method('getName')->willReturn($name); 80 | $parameters[] = $parameter; 81 | } 82 | $this->constructor->method('getParameters')->willReturn($parameters); 83 | $result = $this->testObject->resolve($this->constructor); 84 | $this->assertEquals($expectedResult, $result); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Test/Unit/Code/Generator/UnitTest/SetupMethodBuilderTest.php: -------------------------------------------------------------------------------- 1 | objectManager = new ObjectManager($this); 32 | 33 | $this->testObject = $this->objectManager->getObject( 34 | \Olmer\UnitTestsGenerator\Code\Generator\UnitTest\SetupMethodBuilder::class 35 | ); 36 | } 37 | 38 | /** 39 | * @return array 40 | */ 41 | public function dataProviderForTestBuild() 42 | { 43 | return [ 44 | 'No params, simple test object' => [ 45 | 'setupMethodParamsDefinition' => [], 46 | 'testObjectCreationCode' => "\$this->testObject = \$this->objectManager->getObject(\nTestObject::class,\n" 47 | . " [\n ]\n);", 48 | 'expectedResult' => [ 49 | 'name' => 'setUp', 50 | 'body' => "\$this->objectManager = new ObjectManager(\$this);\n\n" 51 | . "\$this->testObject = \$this->objectManager->getObject(\nTestObject::class,\n" 52 | . " [\n ]\n);", 53 | 'parameters' => [], 54 | 'docblock' => [ 55 | 'shortDescription' => 'Main set up method', 56 | ], 57 | 'returnType' => 'void' 58 | ] 59 | ], 60 | 'Some params, simple test object' => [ 61 | 'setupMethodParamsDefinition' => [ 62 | "\$this->fooFactory = \$this->createMock(FooFactory::class);", 63 | "\$this->fooFactory->method('create')->willReturn(\$this->createMock(Foo::class);" 64 | ], 65 | 'testObjectCreationCode' => "\$this->testObject = \$this->objectManager->getObject(\nTestObject::class,\n" 66 | . " [\n ]\n);", 67 | 'expectedResult' => [ 68 | 'name' => 'setUp', 69 | 'body' => "\$this->objectManager = new ObjectManager(\$this);\n" 70 | . "\$this->fooFactory = \$this->createMock(FooFactory::class);\n" 71 | . "\$this->fooFactory->method('create')->willReturn(\$this->createMock(Foo::class);\n" 72 | . "\$this->testObject = \$this->objectManager->getObject(\nTestObject::class,\n" 73 | . " [\n ]\n);", 74 | 'parameters' => [], 75 | 'docblock' => [ 76 | 'shortDescription' => 'Main set up method', 77 | ], 78 | 'returnType' => 'void' 79 | ] 80 | ] 81 | ]; 82 | } 83 | 84 | /** 85 | * @dataProvider dataProviderForTestBuild 86 | */ 87 | public function testBuild(array $setupMethodParamsDefinition, string $testObjectCreationCode, array $expectedResult) 88 | { 89 | $result = $this->testObject->build($setupMethodParamsDefinition, $testObjectCreationCode); 90 | $this->assertEquals($expectedResult, $result); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /Test/Unit/Code/Generator/UnitTest/TestObjectCreationBuilderTest.php: -------------------------------------------------------------------------------- 1 | objectManager = new ObjectManager($this); 32 | 33 | $this->testObject = $this->objectManager->getObject( 34 | \Olmer\UnitTestsGenerator\Code\Generator\UnitTest\TestObjectCreationBuilder::class, 35 | ); 36 | } 37 | 38 | /** 39 | * @return array 40 | */ 41 | public function dataProviderForTestBuild() 42 | { 43 | return [ 44 | 'No params' => [ 45 | 'objectCreationParams' => [], 46 | 'expectedResult' => "\$this->testObject = \$this->objectManager->getObject(\nFoo::class,\n" 47 | . " [\n\n ]\n);" 48 | ], 49 | 'Some params' => [ 50 | 'objectCreationParams' => [ 51 | " 'param1' => \$this->param1,", 52 | " 'param2' => \$this->param2," 53 | ], 54 | 'expectedResult' => "\$this->testObject = \$this->objectManager->getObject(\nFoo::class,\n" 55 | . " [\n" 56 | . " 'param1' => \$this->param1,\n" 57 | . " 'param2' => \$this->param2,\n" 58 | . " ]\n);" 59 | ] 60 | ]; 61 | } 62 | 63 | /** 64 | * @dataProvider dataProviderForTestBuild 65 | */ 66 | public function testBuild(array $objectCreationParams, string $expectedResult) 67 | { 68 | $result = $this->testObject->build('Foo', $objectCreationParams); 69 | $this->assertEquals($expectedResult, $result); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "olmer/magento-unit-tests-generator", 3 | "description": "Unit Tests Generator", 4 | "license": "MIT", 5 | "authors": [ 6 | { 7 | "name": "Igor Tripolskiy", 8 | "email": "olmer.tripolskiy@gmail.com" 9 | } 10 | ], 11 | "require": { 12 | "magento/framework": "*", 13 | "php": "^7.0 || ^8.0" 14 | }, 15 | "require-dev": { 16 | "phpunit/phpunit": "^9" 17 | }, 18 | "autoload": { 19 | "files": [ 20 | "registration.php" 21 | ], 22 | "psr-4": { 23 | "Olmer\\UnitTestsGenerator\\": "" 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /etc/di.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Olmer\UnitTestsGenerator\Console\Command\Generate 7 | 8 | 9 | 10 | 11 | 12 | 13 | app/code 14 | 15 | 16 | 17 | 18 | 19 | Olmer\UnitTestsGenerator\VirtualType\Io 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /etc/module.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /registration.php: -------------------------------------------------------------------------------- 1 |