Phpunit ZF2单元测试认证
我正在学习单元测试,并试图解决以下问题:Phpunit ZF2单元测试认证,phpunit,zend-framework2,zfcuser,Phpunit,Zend Framework2,Zfcuser,我正在学习单元测试,并试图解决以下问题: Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for zfcUserAuthentication 。。。使用以下给出的唯一答案: 所以我的设置函数看起来是一样的。不幸的是,我收到了错误消息: Zend\Mvc\Exception\InvalidPluginException: Plugin of type Mock_ZfcUserAu
Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for zfcUserAuthentication
。。。使用以下给出的唯一答案:
所以我的设置函数看起来是一样的。不幸的是,我收到了错误消息:
Zend\Mvc\Exception\InvalidPluginException: Plugin of type Mock_ZfcUserAuthentication_868bf824 is invalid; must implement Zend\Mvc\Controller\Plugin\PluginInterface
这是由代码的这一部分引起的(在我的代码中以相同的方式拆分):
$authMock对象显然没有实现plugininterface,我需要实现它才能传递到setService
$authMock不是为了在单元测试中使用而通过的吗?我应该使用不同的(面向单元测试的)setService方法吗
我需要一种方法来处理登录到我的应用程序,否则我的单元测试就没有意义了
谢谢你的建议
==编辑(11/02/2013)===
我想集中在这一部分进行澄清,因为我认为这是问题所在:
// Getting mock of authentication object, which is used as a plugin.
$authMock = $this->getMock('ZfcUser\Controller\Plugin\ZfcUserAuthentication');
// Some expectations of the authentication service.
$authMock -> expects($this->any())
-> method('hasIdentity')
-> will($this->returnValue(true));
$authMock -> expects($this->any())
-> method('getIdentity')
-> will($this->returnValue($ZfcUserMock));
// At this point, PluginManager disallows mock being assigned as plugin because
// it will not implement plugin interface, as mentioned.
$this -> controller->getPluginManager()
->setService('zfcUserAuthentication', $authMock);
如果mock没有处理必要的实现,我怎么能假装登录呢?您的名字间隔或自动加载器有问题 创建模拟时,找不到
ZfcUser\Controller\Plugin\ZfcUserAuthentication
的类定义。所以PHPUnit创建了一个mock,该mock只扩展这个类用于测试。如果该类可用,那么PHPUnit将在创建其mock时使用实际类进行扩展,然后使用父类/接口
您可以在这里看到这种逻辑:
因此,如果没有类或接口,PHPUnit实际上会自己创建一个类或接口,以便mock满足原始类名的类型暗示。但是,不会包括任何父类或接口,因为PHPUnit不知道它们
这可能是因为测试中没有包含正确的名称空间,或者自动加载程序有问题。如果看不到整个测试文件,就很难判断
或者,您可以在测试中模拟
Zend\Mvc\Controller\Plugin\PluginInterface
,而不是模拟ZfcUser\Controller\Plugin\ZfcUserAuthentication
,并将其传递到插件管理器。虽然如果您在代码中为插件输入提示,您的测试仍然无法工作
//Mock the plugin interface for checking authorization
$authMock = $this->getMock('Zend\Mvc\Controller\Plugin\PluginInterface');
// Some expectations of the authentication service.
$authMock -> expects($this->any())
-> method('hasIdentity')
-> will($this->returnValue(true));
$authMock -> expects($this->any())
-> method('getIdentity')
-> will($this->returnValue($ZfcUserMock));
$this -> controller->getPluginManager()
->setService('zfcUserAuthentication', $authMock);
我刚刚为FlashMessenger插件做了一个示例。您应该只使用ControllerPluginManager来覆盖ControllerPlugin。确保应用程序引导调用setApplicationConfig()
我说得对吗?没有必要像模型那样对控制器进行单元测试吗?我发现这就是我保存所有身份验证代码的地方。我最近做了类似的事情,没有任何问题。您的整个testcase类是什么样子的?您的测试引导程序是什么样子的?最后是您尝试测试的操作。单元测试时是否使用特殊的应用程序配置?在这种情况下,测试环境中可能未加载zfcUser模块。
if (!class_exists($mockClassName['fullClassName'], $callAutoload) &&
!interface_exists($mockClassName['fullClassName'], $callAutoload)) {
$prologue = 'class ' . $mockClassName['originalClassName'] . "\n{\n}\n\n";
if (!empty($mockClassName['namespaceName'])) {
$prologue = 'namespace ' . $mockClassName['namespaceName'] .
" {\n\n" . $prologue . "}\n\n" .
"namespace {\n\n";
$epilogue = "\n\n}";
}
$cloneTemplate = new Text_Template(
$templateDir . 'mocked_clone.tpl'
);
//Mock the plugin interface for checking authorization
$authMock = $this->getMock('Zend\Mvc\Controller\Plugin\PluginInterface');
// Some expectations of the authentication service.
$authMock -> expects($this->any())
-> method('hasIdentity')
-> will($this->returnValue(true));
$authMock -> expects($this->any())
-> method('getIdentity')
-> will($this->returnValue($ZfcUserMock));
$this -> controller->getPluginManager()
->setService('zfcUserAuthentication', $authMock);
<?php
namespace SimpleTest\Controller;
use Zend\Test\PHPUnit\Controller\AbstractHttpControllerTestCase;
class SimpleControllerTest extends AbstractHttpControllerTestCase {
public function testControllerWillAddErrorMessageToFlashMessenger()
{
$flashMessengerMock = $this->getMockBuilder('\Zend\Mvc\Controller\Plugin\FlashMessenger', array('addErrorMessage'))->getMock();
$flashMessengerMock->expects($this->once())
->method('addErrorMessage')
->will($this->returnValue(array()));
$serviceManager = $this->getApplicationServiceLocator();
$serviceManager->setAllowOverride(true);
$serviceManager->get('ControllerPluginManager')->setService('flashMessenger', $flashMessengerMock);
$this->dispatch('/error/message');
}
}?>