2010-01-08 6 views
2

Comment tester mes modèles dans une application Zend Framework 1.8+?Comment démarrer le test des modèles Zend Framework?

Disons que mon application est configurée pour commencer les tests. J'ai déjà testé un contrôleur, donc je sais que ça fonctionne. J'ai tous mes contrôleurs étendant mon dossier ControllerTestCase.php:

<?php 
require_once 'Zend/Application.php'; 
require_once 'Zend/Test/PHPUnit/ControllerTestCase.php'; 

abstract class ControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase 
{ 
    public $application; 

    public function setUp() 
    { 
     $this->application = new Zend_Application(
      APPLICATION_ENV, 
      APPLICATION_PATH . '/configs/application.ini' 
     ); 

     $this->bootstrap = array($this, 'appBootstrap'); 
     parent::setUp(); 
    } 

    public function appBootstrap() 
    { 
     $this->application->bootstrap(); 
    } 

    public function tearDown() 
    { 
     Zend_Controller_Front::getInstance()->resetInstance(); 

     $this->resetRequest(); 
     $this->resetResponse(); 

     $this->request->setPost(array()); 
     $this->request->setQuery(array()); 
     parent::tearDown(); 
    } 
} 

Mais maintenant, je veux commencer à tester mes modèles. Il semble que mon ModelTestCase.php ne s'étendrait pas Zend_Test_PHPUnit_ControllerTestCase mais plutôt un Zend_Test_PHPUnit_ModelTestCase, mais il n'existe pas de telle classe que je connaisse. Comment puis-je commencer à tester mes modèles Zend Framework?

Répondre

7

La base ControllerTestCase est fournie pour vous car il existe des étapes complexes nécessaires pour configurer et démonter l'environnement afin de tester un contrôleur. L'entrée est une requête HTTP fictive et la sortie est rendue au format HTML que vous devez extraire pour trouver le contenu attendu.

Un modèle ressemble plus à un simple objet PHP. Il y a moins d'environnement à configurer. L'interface est simplement un appel de méthode à l'objet.

Alors je commencerais une classe TestCase qui s'étend TestCase plaine de PHPUnit, et commencer par l'ajout d'au moins une méthode test (comme fonction vide) pour chaque méthode dans votre classe de modèle. Vous aurez finalement de nombreuses méthodes de test pour chaque méthode de votre classe Model, mais la création de méthodes de test vides est un bon moyen d'éviter d'oublier certaines de vos méthodes Model.

Notez que a Model is not a Table - un modèle généralement utilise un ou plusieurs objets Table. En suivant ce modèle, vous avez la possibilité de créer des tables pour mock objects afin que vous puissiez exécuter la suite de tests sans nécessiter de connexion en direct à une base de données.

Voici un exemple de configuration d'un objet Table simulé, qui est codé en dur pour renvoyer un ensemble de données synthétiques au lieu d'un ensemble de données à partir d'une base de données.

<?php 

class MyModelTest extends PHPUnit_Framework_TestCase 
{ 
    protected $_model; 

    public function setUp() 
    { 
    $foo = $this->getMock('FooTable', array('find')); 
    $foo->expects($this->any()) 
     ->method('find') 
     ->will($this->returnValue(array("id"=>"123"))); 

    $this->_model = new MyModel(); 
    $this->_model->setFooTable($foo); 
    } 

    public function testCountElements() 
    { 
    $this->_model->get(123); 
    $n = $this->_model->countElements(); 
    $this->assertEquals(1, $n); 
    } 

    public function testAsArray() 
    { 
    $this->_model->get(123); 
    $a = $this->_model->asArray(); 
    $this->assertType('array', $a); 
    } 

    public function testAddElement() 
    { 
    // ...etc. 
    } 

    public function testGetElement() 
    { 
    // ...etc. 
    } 

} 
+0

Merci. C'est une très bonne explication. Je me demandais si cela vous dérangerait d'en dire un peu plus sur les modèles incluant/nécessitant/autoloading lorsque vous testez. J'ai un modèle qui étend un modèle abstrait. Peut-être que c'est là que les objets fantaisie entrent? – Andrew

+0

J'ai ajouté quelques détails ci-dessus montrant l'utilisation d'un objet Table faux. Le chargement des classes est totalement ordinaire, vous pouvez le faire avec 'require_once' ou avec le chargement automatique. Je pense que vous pourriez rendre cela plus complexe qu'il ne l'est en réalité. –

Questions connexes