2010-08-12 9 views
3

J'écris un test unitaire avec phpUnit pour tester une application Zend Framework et j'ai quelques problèmes avec le test d'une exception dans la fonction changePassword. Le test n'échoue pas, mais dans l'outil de couverture qui génère html le "throw new Exception ($ tr-> translate ('userOldPasswordIncorrect'));" la ligne n'est pas testée.Exception non testée avec phpUnit?

public function changePassword(array $data, $id) 
{ 
    $user = $this->_em->find('Entities\User', (int) $id); 

    $oldPassword = sha1(self::$_salt . $data['oldPassword']); 
    if ($user->getPassword() !== $oldPassword) { 
     $tr = PC_Translate_MySQL::getInstance(); 
     throw new Exception($tr->translate('userOldPasswordIncorrect')); 
    } 

    $user->setPassword(sha1(self::$_salt . $data['password'])); 

    $this->_em->persist($user); 
    $this->_em->flush(); 
} 

Le test unitaire qui devrait tester l'exception:

/** 
* @depends testFindByAuth 
* @expectedException Exception 
*/ 
public function testChangePasswordWrongOldPassword() 
{ 
    $this->_dummyUser = $this->_user->findByAuth($this->_dummyEmail, $this->_dummyPassword, $this->_reseller); 

    // Try to change the password with a wrong oldPassword 
    $data['oldPassword'] = 'wrongOldPassword'; 
    $data['password'] = $this->_dummyNewPassword; 

    $this->_user->changePassword($data, $this->_dummyUser->getId()); 
} 

Je vais espère que quelqu'un peut me dire ce que je fais mal.

Mise à jour

Le problème était à l'intérieur de la méthode PC_Translate_MySQL :: getInstance(). Il y a eu une exception. Et pendant que j'essayais d'obtenir une exception générale, cela a bien sûr passé. Solution n'utilisez pas une exception générale dans la méthode changePassword.

+0

est testFindByAuth passant? Si ce n'est pas le cas, cela ne permet même pas d'exécuter testChangePasswordWrongOldPassword. –

+0

testFindByAuth passe. – tom

Répondre

4

À mon avis? Une exception est levée de PC_Translate_MySQL::getInstance() ...

C'est le problème avec l'utilisation d'un seul Exception. Cela rend plus difficile de vérifier quelle exception a été lancée. Je suggère de changer la méthode changePassword pour lancer une exception différente. Peut-être un InvalidArgumentException ou un RuntimeException. Et puis tester pour celui-là. Personnellement, j'utilise des exceptions personnalisées tout le temps pour cette raison.

try { 
} catch (DatabaseQueryException $e) { 
    // Handle database error 
} catch (DatabaseConnectionException $e) { 
    // We never even connected... 
} catch (InvalidArgumentException $e) { 
    //... 
} 

I, en règle générale, ne jamais utiliser catch (Exception $e) pour cette raison. Vous ne savez jamais quelle exception vous avez attrapé. (J'ai un gestionnaire d'exception personnalisé défini, donc je ne suis pas mortel si l'application n'attrape pas.Il montre une erreur 500 et enregistre l'exception) ...

+0

Ça doit être ça. Mais alors le rapport de couverture de code montrerait quelle exception a réellement été touchée ... –

+0

Ça le ferait? Bien sûr, cela augmenterait l'exception de lancer, mais si comme moi vous avez un tas de tests, remarquerez-vous 240 visites à l'exception au lieu de 239? AFAIK, le rapport de couverture (HTML ou XML) ne montre pas l'exception réelle qui a été lancée, seulement quelles lignes ont été couvertes (d'où le PO a su poser la question) ... – ircmaxell

+0

Il y avait une exception en effet. Lors du test unitaire, il n'y a pas de $ _SERVER ['SERVER_NAME']; THX! – tom