diff --git a/src/MockDependencies.php b/src/MockDependencies.php new file mode 100644 index 0000000..ac0bafb --- /dev/null +++ b/src/MockDependencies.php @@ -0,0 +1,49 @@ +class = $class; + $this->dependencies = $dependencies; + $depMap = []; + foreach ($dependencies as $dep) { + $depMap[$dep['name']] = $dep['value']; + } + $this->dependenciesMap = $depMap; + } + + + + public function get(string $name) + { + return $this->dependenciesMap[$name] ?? null; + } + + public function getValues() + { + $depValues = []; + foreach ($this->dependencies as $dep) { + $depValues[] = $dep['value']; + } + return $depValues; + } + + public function instantiate() + { + return new $this->class(...$this->getValues()); + } +} diff --git a/src/TestCase.php b/src/TestCase.php index f36c042..87ab351 100644 --- a/src/TestCase.php +++ b/src/TestCase.php @@ -1,4 +1,5 @@ getMock(); } - + /** * Helper method for loading test configuration from a file. @@ -92,4 +97,55 @@ public static function getConfig($env, $path = null, $default = array()) return null; } + + /** + * Create a MockDependencies instance from a class name to simplyfy creation of classes where all or most dependencies are mocked. + * + * @param string $class The full name of the class + * @param array $overrides Optional. Hashmap were the keys are the names of the parameters of the class and values are the instance to use. + * Every parameter not set here, will be automatically mocked instead + * + * @return MockDependencies The MockDependencies instance that can be used to create instances of the class + * + * @throws Exception If a parameter of the class does not have a type, no default value and is also not in the overrides array + * */ + public function getMockDependencies(string $class, array $overrides = []) + { + $reflection = new ReflectionClass($class); + $constructor = $reflection->getConstructor(); + $parameters = $constructor->getParameters(); + + $dependencies = []; + foreach ($parameters as $parameter) { + $name = $parameter->getName(); + $type = $parameter->getType(); + $override = $overrides[$name] ?? null; + if ($override) { + $dependency = $override; + } elseif ($parameter->isDefaultValueAvailable()) { + $dependency = $parameter->getDefaultValue(); + } else { + if (is_null($type)) { + throw new Exception("dependency $name has no type defined and is not in overrides array"); + } + $typeName = $type->getName(); + switch ($typeName) { + case 'int': + $dependency = 0; + break; + case 'string': + $dependency = ''; + break; + case 'array': + $dependency = []; + break; + default: + $dependency = $this->createMock($typeName); + break; + } + } + $dependencies[] = ['name' => $name, 'value' => $dependency]; + } + return new MockDependencies($class, $dependencies); + } }