Created
January 11, 2014 19:31
-
-
Save tomphp/8375614 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Problem: | |
// I'm testing a method which adds a service to a service container class which takes a service | |
// name and a callback which creates the service. Like so: | |
function load(ServiceContainer $container) | |
{ | |
$container->set( | |
'event_dispatcher.listeners.db_extension', | |
function ($sc) { | |
return new SomeClass(); | |
} | |
); | |
} | |
// Using PHPUnit I would do something along the lines of this | |
public function testConfiguresServiceContainer() | |
{ | |
$sc = new ServiceContainer(); | |
$this->objectBeingTested->load($sc); | |
$this->assertInstanceOf( | |
'SomeClass', | |
$sc->get('event_dispatcher.listeners.db_extension') | |
); | |
} | |
// Using PHPSpec I came up with these 2 solutions | |
public function it_should_attach_listener() | |
{ | |
// Using a real service container, I would prefer this route | |
// and it complies with "Don't mock what you don't own" | |
$container = new ServiceContainer(); | |
$this->load($container); | |
// Ugly hack: throw exception if "assert" fails | |
if (!$container->get('event_dispatcher.listeners.db_extension') instanceof RepositoryListener) { | |
throw new \Exception( | |
'Service event_dispatcher.listeners.db_extension does not return ' | |
. ' TomPHP\PhpSpec\DbExtension\Listener\RepositoryListener' | |
); | |
} | |
} | |
// This is probably a more elegant solution but I feel mocking the ServiceContainer is wrong | |
// as it's part of the framework rather than something in my module | |
public function it_should_attach_listener_with_mock(ServiceContainer $container) | |
{ | |
$container->setShared( | |
'event_dispatcher.listeners.db_extension', | |
Argument::that(function ($factory) { | |
return $factory() instanceof RepositoryListener; | |
}) | |
); | |
$this->load($container); | |
} | |
// One possible final solution might be that a "unit" shouldn't be doing such a thing and this | |
// code might be considered part of the configuration and therefore falls into integration testing | |
// Would love to hear some opinions! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment