2012-12-25 71 views
3

我有我自己的SessionManager服務的單元測試問題。我在單元測試中沒有錯誤,但會話不是在數據庫中創建的,我無法寫入存儲。這裏是我的代碼:Zend Framework 2 - 如何單元測試自己的會話服務?

SessionManagerFactory:

namespace Admin\Service; 

use Zend\ServiceManager\FactoryInterface; 
use Zend\ServiceManager\ServiceLocatorInterface; 
use Zend\ServiceManager\ServiceManager; 
use Zend\Session\SaveHandler\DbTableGatewayOptions as SessionDbSavehandlerOptions; 
use Zend\Session\SaveHandler\DbTableGateway; 
use Zend\Session\Config\SessionConfig; 
use Zend\Session\SessionManager; 
use Zend\Db\TableGateway\TableGateway; 

class SessionManagerFactory implements FactoryInterface 
{ 
    public function createService(ServiceLocatorInterface $serviceLocator) 
    { 
     return $this; 
    } 

    public function setUp(ServiceManager $serviceManager) 
    { 
     $sessionOptions = new SessionDbSavehandlerOptions(); 
     $sessionOptions->setDataColumn('data') 
         ->setIdColumn('id') 
         ->setModifiedColumn('modified') 
         ->setLifetimeColumn('lifetime') 
         ->setNameColumn('name'); 
     $dbAdapter = $serviceManager->get('Zend\Db\Adapter\Adapter'); 
     $sessionTableGateway = new TableGateway('zf2_sessions', $dbAdapter); 
     $sessionGateway = new DbTableGateway($sessionTableGateway, $sessionOptions); 
     $config = $serviceManager->get('Configuration'); 
     $sessionConfig = new SessionConfig(); 
     $sessionConfig->setOptions($config['session']); 
     $sessionManager = new SessionManager($sessionConfig); 
     $sessionManager->setSaveHandler($sessionGateway); 

     return $sessionManager; 
    } 
} 

GetServiceConfig()方法從Module.phpAdmin命名空間:

public function getServiceConfig() 
    { 
     return array(
      'factories' => array(
       'Zend\Authentication\Storage\Session' => function($sm) { 
        return new StorageSession(); 
       }, 
       'AuthService' => function($sm) { 
        $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter'); 
        $authAdapter = new AuthAdapter($dbAdapter, 'zf2_users', 'email', 'password'); 

        $authService = new AuthenticationService(); 
        $authService->setAdapter($authAdapter); 
        $authService->setStorage($sm->get('Zend\Authentication\Storage\Session')); 

        return $authService; 
       }, 
       'SessionManager' => function($serviceManager){ 
        $sessionManager = new SessionManagerFactory(); 
        return $sessionManager->setUp($serviceManager); 
       } 
      ) 
     ); 
    } 

而且從單元測試文件setUp() mehod:

protected function setUp() 
    { 
     $bootstrap    = \Zend\Mvc\Application::init(include 'config/app.config.php'); 
     $this->controller  = new SignController; 
     $this->request   = new Request; 
     $this->routeMatch  = new RouteMatch(array('controller' => 'sign')); 
     $this->event   = $bootstrap->getMvcEvent(); 

     // Below line should start session and storage it in Database. 
     $bootstrap->getServiceManager()->get('SessionManager')->start(); 
     // And this line should add test variable to default namespace of session, but doesn't - blow line is only for quick test. I will write method for test write to storage. 
     Container::getDefaultManager()->test = 12; 

     $this->event->setRouteMatch($this->routeMatch); 
     $this->controller->setEvent($this->event); 
     $this->controller->setEventManager($bootstrap->getEventManager()); 
     $this->controller->setServiceLocator($bootstrap->getServiceManager()); 
    } 

如何測試這個se服務和爲什麼會話不被創建?

+0

這有什麼好運氣? –

回答

2

我認爲你誤解了工廠模式。你的工廠應該如下圖所示。據我所知,單獨的setUp方法根本不會被調用。你不要在任何地方手動調用它。

class SessionManagerFactory implements FactoryInterface 
{ 
    public function createService(ServiceLocatorInterface $serviceLocator) 
    { 
     $sessionOptions = new SessionDbSavehandlerOptions(); 
     $sessionOptions->setDataColumn('data') 
         ->setIdColumn('id') 
         ->setModifiedColumn('modified') 
         ->setLifetimeColumn('lifetime') 
         ->setNameColumn('name'); 
     $dbAdapter = $serviceManager->get('Zend\Db\Adapter\Adapter'); 
     $sessionTableGateway = new TableGateway('zf2_sessions', $dbAdapter); 
     $sessionGateway = new DbTableGateway($sessionTableGateway, $sessionOptions); 
     $config = $serviceManager->get('Configuration'); 
     $sessionConfig = new SessionConfig(); 
     $sessionConfig->setOptions($config['session']); 
     $sessionManager = new SessionManager($sessionConfig); 
     $sessionManager->setSaveHandler($sessionGateway); 

     return $sessionManager; 

    } 

} 

以下所有代碼適用於我。我認爲你錯過了一些其他的東西,但上面應該修復它。請看下面的SEE ME評論。另外,像下面這樣爲你的Module.php添加一個onBootstrap方法,並確保在你的情況下調用$sessionManager = $serviceManager->get('SessionManager');,這樣你的SessionFactory實際上就被調用了。你已經在單元測試的setup()函數中調用了它,但是如果你在模塊中調用它,你將不必親自手動調用它。

在application.config我有這個

'session' => array(
     'name'    => 'PHPCUSTOM_SESSID', 
     'cookie_lifetime'  => 300, //1209600, //the time cookies will live on user browser 
     'remember_me_seconds' => 300, //1209600 //the time session will live on server 
     'gc_maxlifetime'  => 300 
    ) 
'db' => array(
     'driver' => 'Pdo_Sqlite', 
     'database' => '/tmp/testapplication.db' 
    ), 

我的會話工廠是非常相似的,但我有一個代碼額外的行。尋找評論。

use Zend\ServiceManager\FactoryInterface, 
    Zend\ServiceManager\ServiceLocatorInterface, 
    Zend\Session\SessionManager, 
    Zend\Session\Config\SessionConfig, 
    Zend\Session\SaveHandler\DbTableGateway as SaveHandler, 
    Zend\Session\SaveHandler\DbTableGatewayOptions as SaveHandlerOptions, 
    Zend\Db\Adapter\Adapter, 
    Zend\Db\TableGateway\TableGateway; 

class SessionFactory 
    implements FactoryInterface 
{ 

    public function createService(ServiceLocatorInterface $sm) 
    { 
     $config = $sm->has('Config') ? $sm->get('Config') : array(); 
     $config = isset($config[ 'session' ]) ? $config[ 'session' ] : array(); 
     $sessionConfig = new SessionConfig(); 
     $sessionConfig->setOptions($config); 

     $dbAdapter = $sm->get('\Zend\Db\Adapter\Adapter'); 

     $sessionTableGateway = new TableGateway('sessions', $dbAdapter); 
     $saveHandler = new SaveHandler($sessionTableGateway, new SaveHandlerOptions()); 

     $manager = new SessionManager(); 
     /******************************************/ 
     /* SEE ME : I DON'T SEE THE LINE BELOW IN YOUR FACTORY. It probably doesn't matter though. 
     /******************************************/ 

     $manager->setConfig($sessionConfig); 
     $manager->setSaveHandler($saveHandler); 

     return $manager; 
    } 

在我的模塊之一,我有以下

public function onBootstrap(EventInterface $e) 
    { 

     // You may not need to do this if you're doing it elsewhere in your 
     // application 
     /* @var $eventManager \Zend\EventManager\EventManager */ 
     /* @var $e \Zend\Mvc\MvcEvent */ 
     $eventManager = $e->getApplication()->getEventManager(); 

     $serviceManager = $e->getApplication()->getServiceManager(); 

     $moduleRouteListener = new ModuleRouteListener(); 
     $moduleRouteListener->attach($eventManager); 

     try 
     { 
      //try to connect to the database and start the session 
      /* @var $sessionManager SessionManager */ 
      $sessionManager = $serviceManager->get('Session'); 

      /******************************************/ 
      /* SEE ME : Make sure to start the session 
      /******************************************/ 
      $sessionManager->start(); 
     } 
     catch(\Exception $exception) 
     { 
      //if we couldn't connect to the session then we trigger the 
      //error event 
      $e->setError(Application::ERROR_EXCEPTION) 
       ->setParam('exception', $exception); 
      $eventManager->trigger(MvcEvent::EVENT_DISPATCH_ERROR, $e); 
     } 
    } 

} 

這是我getServiceConfigMethod

public function getServiceConfig() 
{ 
    return array(
     'factories' => array(
      'Session' => '\My\Mvc\Service\SessionFactory', 
      '\Zend\Db\Adapter\Adapter' => '\Zend\Db\Adapter\AdapterServiceFactory' 
     ) 
    ); 
} 

我使用sqllite此刻因此此表中存在的sqllite文件已經。

如果您使用的是mysql,它也應該存在於該數據庫中,您應該在application.config.php文件中更改您的db設置。

相關問題