I'm unit testing a ZF2 Controller, below is the test class:
<?php
class RestControllerTest extends AbstractHttpControllerTestCase
{
public function setUp()
{
Bootstrap::init();
$this->setApplicationConfig(Bootstrap::getConfig());
parent::setup();
}
public function testCreate()
{
$paramsArr = array(/** Params Here **/);
$this->dispatch('/transcode', 'POST', $paramsArr);
$this->assertResponseStatusCode(204);
$this->assertControllerName('Transcode\Controller\Rest');
$this->assertMatchedRouteName('transcode');
}
}
My unit test is failing, indicating a ServiceNotFoundException on logger.transcode, which is attached to the eventmanager onBootstrap of the Transcode module:
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$app = $e->getTarget();
$serviceManager = $app->getServiceManager();
$eventManager->attach($serviceManager->get('Transcode\Listener'));
}
Transcode\Listener is instantiated via a Factory:
public function createService(ServiceLocatorInterface $serviceLocator)
{
$logger = $serviceLocator->get('logger.transcode');
$service = new TranscodeListener($logger);
return $service;
}
And finally, logger.transcode is set via a config file which creates logger.transcode as an abstract factory in the EnliteMonolog module.
Any idea why the unit test can't attach the listener to workflow?
Per request in the comments, the Bootstrap file is below, although it's a standard ZF2 Test Bootstrap file:
<?php
namespace TranscodeTest;
use Zend\Loader\AutoloaderFactory;
use Zend\Mvc\Service\ServiceManagerConfig;
use Zend\ServiceManager\ServiceManager;
use Zend\Stdlib\ArrayUtils;
use RuntimeException;
use Dotenv;
error_reporting(E_ALL | E_STRICT);
chdir(__DIR__);
class Bootstrap
{
protected static $serviceManager;
protected static $config;
protected static $bootstrap;
public static function init()
{
// Load the user-defined test configuration file, if it exists; otherwise, load
if (is_readable(__DIR__ . '/TestConfiguration.php')) {
$testConfig = include __DIR__ . '/TestConfiguration.php';
}
$zf2ModulePaths = array();
if (isset($testConfig['module_listener_options']['module_paths'])) {
$modulePaths = $testConfig['module_listener_options']['module_paths'];
foreach ($modulePaths as $modulePath) {
if (($path = static::findParentPath($modulePath)) ) {
$zf2ModulePaths[] = $path;
}
}
}
$zf2ModulePaths = implode(PATH_SEPARATOR, $zf2ModulePaths) . PATH_SEPARATOR;
$zf2ModulePaths .= getenv('ZF2_MODULES_TEST_PATHS') ?: (defined('ZF2_MODULES_TEST_PATHS') ? ZF2_MODULES_TEST_PATHS : '');
static::initAutoloader();
// use ModuleManager to load this module and it's dependencies
$baseConfig = array(
'module_listener_options' => array(
'module_paths' => explode(PATH_SEPARATOR, $zf2ModulePaths),
),
);
$config = ArrayUtils::merge($baseConfig, $testConfig);
$serviceManager = new ServiceManager(new ServiceManagerConfig());
$serviceManager->setService('ApplicationConfig', $config);
$serviceManager->get('ModuleManager')->loadModules();
static::$serviceManager = $serviceManager;
static::$config = $config;
}
public static function getServiceManager()
{
return static::$serviceManager;
}
public static function getConfig()
{
return static::$config;
}
protected static function initAutoloader()
{
$vendorPath = static::findParentPath('vendor');
if (is_readable($vendorPath . '/autoload.php')) {
$loader = include $vendorPath . '/autoload.php';
} else {
$zf2Path = getenv('ZF2_PATH') ?: (defined('ZF2_PATH') ? ZF2_PATH : (is_dir($vendorPath . '/ZF2/library') ? $vendorPath . '/ZF2/library' : false));
if (!$zf2Path) {
throw new RuntimeException('Unable to load ZF2. Run `php composer.phar install` or define a ZF2_PATH environment variable.');
}
include $zf2Path . '/Zend/Loader/AutoloaderFactory.php';
}
AutoloaderFactory::factory(array(
'Zend\Loader\StandardAutoloader' => array(
'autoregister_zf' => true,
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/' . __NAMESPACE__,
),
),
));
if (getenv('APPLICATION_ENV') != 'PRODUCTION') {
Dotenv::load('../../../config');
}
}
protected static function findParentPath($path)
{
$dir = __DIR__;
$previousDir = '.';
while (!is_dir($dir . '/' . $path)) {
$dir = dirname($dir);
if ($previousDir === $dir) return false;
$previousDir = $dir;
}
return $dir . '/' . $path;
}
}
Bootstrap::init();