I'm unit testing a Dependency Injection Container.
At the most basic level, I'm testing that object graph creation is happening correctly. This uses a mixture of reflection and rules loaded into the DIC.
The DIC works using class definitions and because of the dependencyless nature of mocks, am I right in thinking they are not suitable for this task?
Without using mocks, here's how one of my tests looks:
public function testObjectGraphCreation() {
$a = $this->dic->create('A');
$this->assertInstanceOf('B', $a->b);
$this->assertInstanceOf('C', $a->b->c);
$this->assertInstanceOf('D', $a->b->c->d);
$this->assertInstanceOf('E', $a->b->c->e);
$this->assertInstanceOf('F', $a->b->c->e->f);
}
(obviously this chaining and public dependencies are only there for the test)
And I've defined several classes in order to make this work:
class A {
public $b;
public function __construct(B $b) {
$this->b = $b;
}
}
class B {
public $c;
public function __construct(C $c) {
$this->c = $c;
}
}
class C {
public $d;
public $e;
public function __construct(D $d, E $e) {
$this->d = $d;
$this->e = $e;
}
}
class D {
}
class E {
public $f;
public function __construct(F $f) {
$this->f = $f;
}
}
class F {}
Because of the nature of this test, am I right in thinking I cannot use generated mocks for this?
This looks more like an integration test where you're testing the entire DI system at once. Instead, see where you can mock parts of the system--not the objects it creates. Without seeing the classes involved, I can't make an educated guess.
While you probably can't use PHPUnit's mock objects, you can roll your own one-off mocks that do the same thing. For example, to test setting a property by calling Database::setPassword with a value taken from the container you'd create a mock Database class, put the password into the container, and ask the container to create the object.
class MockDatabase {
public $passwordSet = false;
public function setPassword($password) {
if ($password != 'password') {
throw new InvalidArgumentException('Expected "password"');
}
$this->passwordSet = true;
}
}
...
function testInjectProperty() {
$container = Container::create(array(
'password' => 'password',
));
$database = $container->create('MockDatabase');
self::assertTrue($database->passwordSet);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With