Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions src/MockDependencies.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

declare(strict_types=1);

namespace Horde\Test;

/**
* Class that hold a number of dependencies and a class name
* Can be used to create instances of that class or modify dependencies
*/
class MockDependencies
{
protected array $dependencies;
protected array $dependenciesMap;
protected string $class;


public function __construct(string $class, array $dependencies)
{
$this->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());
}
}
60 changes: 58 additions & 2 deletions src/TestCase.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

/**
* Basic Horde test case helper.
*
Expand All @@ -11,8 +12,12 @@
* @license http://www.horde.org/licenses/lgpl21 LGPL
* @link http://www.horde.org/components/Horde_Test
*/

namespace Horde\Test;
use \Horde_Support_Backtrace;

use Horde_Support_Backtrace;
use ReflectionClass;

/**
* Basic Horde test case helper.
*
Expand Down Expand Up @@ -47,7 +52,7 @@ public function getMockSkipConstructor($className, array $methods = array(), arr
}
return $builder->getMock();
}


/**
* Helper method for loading test configuration from a file.
Expand Down Expand Up @@ -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);
}
}