0

在某些情况下,我会通过它们的完整类名从 ServiceManager 中检索实例,例如:

$someThing = $serviceManager->get('MyModule\Some\Nice\Lib\SomeThing');

这对于 HTTP MVC 请求非常有效,但是,当使用 phpunit 时,ServiceManager 找不到它。(它会抛出Zend\ServiceManager\Exception\ServiceNotFoundException异常消息“Zend\ServiceManager\ServiceManager::get无法获取或创建...的实例”)

我正在使用文档中的默认测试引导示例,并且我在不同机器上的两个不同项目中遇到了这个问题,所以我想这是一个普遍的问题。

我的第一个猜测是它与 MVC 或应用程序有关,因为这很可能是测试和 http 之间唯一真正的区别。我什至在两种模式下都转储了 SM 实例并将它们相互比较,查看源代码并搜索网络。

不幸的是,由于我的劳动合同,我无法粘贴任何代码。但是,正如我所说,我认为这是一个普遍问题,因此您应该能够轻松地重现它。

有谁知道是什么导致了这个问题以及如何解决它?

4

2 回答 2

0

确保您将模块添加到测试配置:

return array(
    'modules' => array(
        'MyModule',
        //...
    ),
    //...
);

否则 ModuleManager 将不会尝试加载它,因此模块自动加载器将不会被注册

于 2013-01-04T08:05:22.223 回答
0

我设法找到了问题所在。

当您使用创建具有完整类名的实例时ServiceManager,实际上默认情况下无法创建它。但是,如果可能,它会将任务委托给附加到它的抽象工厂。

现在,当您使用 DiFactory 创建 Di 实例时,工厂会将 a 注册DiAbstractServiceFactory到 SM。而且,你猜对了,这个抽象工厂能够通过类的全名来实例化类。

Di在这个项目中很少使用(因为我并没有真正适应它并且一开始就用错了;我现在知道得更好了),这就是为什么我实例化的唯一点Di是在模块的方法内部onBootstrap()。这在 MVC 上下文中很好,但是,作为onBootstrap()HTTP MVC 事件处理程序,它不会在我的测试应用程序中调用。因此, noDi​​在任何时候都被实例化,因此,ServiceManager没有DiAbstractServiceFactory附加到它,因此它不能委托get()调用,因此它无法通过它们的完整类名来实例化类。

就这么简单!:-)

显而易见的解决方案:在测试应用程序中创建一个Di实例。

于 2013-01-07T11:14:37.440 回答