2013-02-10 22 views
23

Ben birim test hakkında öğrenme ve ben şu sorunu çözmeye çalıştı: YaniZF2 birim test kimlik doğrulama

Simple ZF2 Unit Tests for a controller using ZfcUser

: verilen tek cevap kullanarak ...

Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for zfcUserAuthentication 

benim setUp işlevim aynı görünüyor.

Zend\Mvc\Exception\InvalidPluginException: Plugin of type Mock_ZfcUserAuthentication_868bf824 is invalid; must implement Zend\Mvc\Controller\Plugin\PluginInterface 

Kodun (aynı şekilde benim kodunda bölünmüş) bu kısmında neden olunabilir:

$this -> controller->getPluginManager() 
->setService('zfcUserAuthentication', $authMock); // Error refers to this line. 

$ authMock nesne görünüşte değil maalesef şu hata mesajını alıyorum setService'ye geçmek için uygulamak zorunda olduğum plugininterface'yi uygulamak.

$ authMock, birim sınamasında kullanıldığından oraya iletilmek istenmiyor mu? Farklı (birim test odaklı) setService yöntemi kullanmalı mıyım?

Uygulamamda oturum açmayı idare etmenin bir yoluna ihtiyacım var veya birim testim anlamsız.

Her türlü öneriniz için teşekkürler.

// 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); 

ise:

=== Düzenleme (2013/11/02) ===

Ben bu sorun alanı olduğunu düşünüyorum olarak, açıklama için bu bölümü odaklanmak istedik sahte gerekli uygulamaları işlemez, başka nasıl giriş yapmalıyım?

+0

Modeller gibi ünite test denetleyicileri için gerekli olmadığı doğru muyum? Tüm kimlik doğrulama kodumu sakladığım yer burası. – Shoreline

+0

Son zamanlarda hiç sorun yaşamadan benzer bir şey yaptım. Komple test sınıfınız neye benziyor? Ayrıca test bootstrap'iniz neye benziyor? Sonunda test etmeye çalıştığın eylem. – Ruben

+0

Birim testi yaparken özel bir uygulama yapılandırması kullanıyor musunuz? Bu durumda zfcUser modülünün test ortamında yüklenmemiş olması mümkündür. – SmasherHell

cevap

3

Ad aralığı veya otomatik yükleyicinizle ilgili bir sorununuz var.

Senin alayını oluştururken, ZfcUser\Controller\Plugin\ZfcUserAuthentication sınıf tanımı bulunamadı. Bu yüzden PHPUnit, bu sınıfı yalnızca testiniz için genişleten bir alay oluşturur. Eğer sınıf mevcut olsaydı, PHPUnit, gerçek sınıfını alayını yaparken uzatmak için kullanır, daha sonra ana sınıfları/arayüzleri kullanır.

Burada bu mantık görebilirsiniz: hayır sınıf veya arabirim varsa sahte orijinal sınıf adının Tür Dayatma karşılayacak şekilde https://github.com/sebastianbergmann/phpunit-mock-objects/blob/master/PHPUnit/Framework/MockObject/Generator.php

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' 
     ); 

Yani, PHPUnit aslında bir kendini yaratacaktır. Ancak, PHPUnit bunların farkında olmadığı için, herhangi bir üst sınıf veya arabirim eklenmeyecektir.

Bunun nedeni, testinizdeki uygun ad alanını veya otomatik yükleyicinizde sorun yaşamanızdır. Test dosyasının tamamını görmeden söylemek zor.


Alternatif yerine ZfcUser\Controller\Plugin\ZfcUserAuthentication alaya yerine, sizin testinde Zend\Mvc\Controller\Plugin\PluginInterface alay ve eklenti yöneticisi içine geçebileceği. Kodunuzda eklenti için ipucu yazıyor olsanız da, testiniz hala çalışmayacaktır.

//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); 
0

FlashMessenger eklentisi için bir örnek verdim. ControllerPlugin'i geçersiz kılmak için ControllerPluginManager'ı kullanmalısınız. Uygulama önyükleyicinizin setApplicationConfig();

<?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'); 

    } 
}?>