Skip to content

Instantly share code, notes, and snippets.

@tomphp
Created January 11, 2014 19:31
Show Gist options
  • Save tomphp/8375614 to your computer and use it in GitHub Desktop.
Save tomphp/8375614 to your computer and use it in GitHub Desktop.
<?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