2013-04-19 22 views
7

adlı bir ispat yöntemi, phpunit için yeni ve sahte nesnelerle ilgili belgeleri okudum ama çok açık değil.PHPUnit alayları -

Bir sınıf içinde bir yöntem denen basit bir sınama yazmaya çalışıyorum. Aşağıdaki kodla, Client :: exchangeArray çağrıldığında, Client :: getInputFilter öğesine bir çağrı yapıldığını test ediyorum. İşte

class Client implements InputFilterAwareInterface 
{ 

public function getInputFilter() { 
    if(!$this->_inputFilter){ 
     $inputFactory = new InputFactory(); 
     $inputFilter = new InputFilter(); 

     $inputFilter->add($inputFactory->createInput(array(
      'name' => 'id', 
      'required' => true, 
      'filters' => array(
       array(
        'name' => 'Int' 
       ) 
      ) 
     ))); 

     $inputFilter->add($inputFactory->createInput(array(
      'name' => 'name', 
      'required' => true, 
      'filters' => array(
       array(
        'name' => 'StripTags' 
       ), 
       array(
        'name' => 'StringTrim' 
       ), 
       array(
        'name' => 'StripNewLines'  
       ), 
       array(
        'name' => 'Alpha' 
       ) 
      ), 
      'validators' => array(
       array(
        'name' => 'StringLength', 
        'options' => array(
         'encoding' => 'UTF-8', 
         'min' => 2, 
         'max' => 100 
        ) 
       ) 
      ) 
     ))); 

     $inputFilter->add($inputFactory->createInput(array(
      'name' => 'surname', 
      'required' => true, 
      'filters' => array(
       array(
        'name' => 'StripTags' 
       ), 
       array(
        'name' => 'StringTrim' 
       ) 
      ), 
      'validators' => array(
       array(
        'name' => 'StringLength', 
        'options' => array(
         'encoding' => 'UTF-8', 
         'min' => 2, 
         'max' => 100 
        ) 
       ) 
      ) 
     ))); 

     $inputFilter->add($inputFactory->createInput(array(
      'name' => 'email', 
      'required' => false, 
      'filters' => array(
       array(
        'name' => 'StripTags' 
       ), 
       array(
        'name' => 'StringTrim' 
       ) 
      ), 
      'validators' => array(
       array(
        'name' => 'StringLength', 
        'options' => array(
         'encoding' => 'UTF-8', 
         'min' => 2, 
         'max' => 150 
        ) 
       ), 
       array(
        'name' => 'EmailAddress' 
       ) 
      ) 
     ))); 

     $this->_inputFilter = $inputFilter; 
    } 
    return $this->_inputFilter; 
} 

public function exchangeArray($data){ 
    $inputFilter = $this->getInputFilter(); 
    $inputFilter->setData($data); 
    if(!$inputFilter->isValid()){ 
     throw new \Exception('Invalid client data'); 
    } 

    $cleanValues = $inputFilter->getValues(); 

    $this->_id = (isset($cleanValues['id']) ? $cleanValues['id'] : null); 
    $this->_name = (isset($cleanValues['name']) ? $cleanValues['name'] : null); 
    $this->_surname = (isset($cleanValues['surname']) ? $cleanValues['surname'] : null); 
    $this->_email = (isset($cleanValues['email']) ? $cleanValues['email'] : null); 
    }   
} 

benim test durumdur:

public function testExchangeArrayCallsInputFilter(){ 
    $data = array('id' => 54, 
      'name' => 'john', 
      'surname' => 'doe', 
      'email' => '[email protected]' 
    ); 

    $mock = $this->getMock('Client', array('exchangeArray')); 
    $mock->expects($this->once()) 
     ->method('getInputFilter'); 
    $mock->exchangeArray($data); 
} 

... ve ben aşağıdaki hatayı alıyorum: ben yanlış gidiyorum

Expectation failed for method name is equal to when invoked 1 time(s). Method was expected to be called 1 times, actually called 0 times.

?

cevap

9

Her şey neyi test etmek istediğinize ve ne yapmak istediğinize bağlıdır. Testinizin adını temel alarak test exchangeArray yöntemini istediğinizi varsayalım.

getMock yöntemi, sahte olmasını istediğiniz yöntemlerin ikinci bağımsız değişken adlarını alır. Bu asla çağrılmayacakları anlamına gelir.

$mock = $this->getMock('Client', array('getInputFilter')); 
$mock->expects($this->once()) 
    ->method('getInputFilter'); 
$mock->exchangeArray($data); 

Ancak dikkatli olun: Test exchangeArray yöntemi ve sahte getInputFilter istiyorsanız

Yani, aşağıda olduğu gibi ikinci argüman "getInputFilter" geçmelidir. Sahibine hiçbir şey geri vermediğini söylemedin, bu yüzden boş değer geri dönecek. Bu, exchangeArray yönteminin ikinci satırında önemli bir hata alacağınız anlamına gelir (nesne olmayan yöntemde yöntemi çağırmaya çalışmak).

// $preparedFilterObject = ... 
$mock = $this->getMock('Client', array('getInputFilter')); 
$mock->expects($this->once()) 
    ->method('getInputFilter') 
    ->will($this->returnValue($preparedFilterObject); 
$mock->exchangeArray($data); 

Ve getInputFilter yöntemi "gerçek" çağırmak istiyorum - o zaman sadece bu yöntemi alay edemez: Sen, mesela ile başa çıkmak için bazı sahte filtre nesnesini hazırlamalısınız.

+0

Cevabınız için teşekkür ederiz. Her iki yöntem için zaten uygulamalarım var. Sadece yöntemlerin doğru sırayla çağrıldığını kontrol etmek istedim ve daha sonra belirli parametrelerle çağrıldıklarını. Yöntemlerin sahte nesneler olmadan çağrıldığını kontrol etmenin bir yolu var mı? –

+0

Hayır, yok. Ama eğer ikinci yöntemi çağırmak istiyorsanız, aslında çağrılmış olup olmadığını kontrol etmeniz gerekmez, çünkü eğer o değilse, $ inputFilter nesnesini alamazsınız ve yine de başarısızlığı test edebilirsiniz. – Cyprian

+1

Diğer taraftan, test geçme ve ikinci yöntem çağrılmadıysa (sizin durumunuzda gerçekleşmeyecek, ancak bazı durumlarda olabilir) kod kapsamı raporunda bunu farkedeceksiniz. Ve bu, ya bu ikinci aramaya ihtiyacınız olmadığını ya da testlerinizi düzelttiğiniz anlamına gelebilir. İkinci yönteminizin bazı iç nesne özellikleri belirlemesi durumunda, yöntemin çağrılıp çağrılmadığını kontrol etmek için bu özelliğe karşı da test edebilirsiniz. – Cyprian