Dependency Injector
A simple and lightweight dependency injector. You will need nothing more to tests your old legacy code.
What is a dependency
Something that your script needs to work correct. For example an instance of Calculator
or Config
. Or even
a class itself.
Examples
Config
The <?php
class Config {
private static $_instance;
public $database = [
'host' => 'localhost',
'user' => 'john',
'password' => 'does.secret',
'database' => 'john_doe'
];
public $redis = ['host' => 'localhost'];
private function __construct() {
// maybe some logic to change the config or initialize variables
}
public static function getInstance() {
if (!self::$_instance) {
self::$_instance = new Config();
}
return self::$_instance;
}
}
class_alias('DependencyInjector', 'DI'); // create an alias for easier access
DI::set('config', function() { return Config::getInstance(); });
function someStaticFunction() {
// before
if (empty(Config::getInstance()->database['host'])) {
throw new Exception('No database host configured');
}
// now
if (empty(DI::config()->database['host'])) {
throw new Exception('No database host configured');
}
// or if you prefer
if (empty(DI::get('config')->database['host'])) {
throw new Exception('No database host configured');
}
}
The database connection
<?php
DI::set('database', function() {
$dbConfig = DI::config()->database;
$mysql = new mysqli($dbConfig['host'], $dbConfig['user'], $dbConfig['password'], $dbConfig['database']);
if (!empty($mysql->connect_error)) {
throw new Exception('could not connect to database (' . $mysql->connect_error . ')');
}
return $mysql;
});
function someStaticFunction() {
// before it maybe looked like this
$mysql = MyApp::getDatabaseConnection();
// now
$mysql = DI::database();
$mysql->query('SELECT * FROM table');
}
The problem before: you can not mock the static function MyApp::getDatabaseConnection()
. You also can not mock the
static function DI::database()
or DI::get('database')
. But you can set the dependency to return a mock object:
<?php
class ApplicationTest extends PHPUnit_Framework_TestCase {
public function testSomeStaticFunction() {
$mock = $this->getMock(mysqli::class);
$mock->expects($this->once())->method('query')
->with('SELECT * FROM table');
DI::set('database', function() use($mock) { return $mock; });
someStaticFunction();
}
}