2 Stimmen

Einheitstests von Zend-Controllern mit Fake-Modellen und -Diensten.

Ich habe viele Zend Controller Test Tutorials gelesen, aber ich kann keines finden, das erklärt, wie man einen Controller testet, der Modelle verwendet und diese Modelle parodiert.

Ich habe die folgende Controller-Aktion:-

function indexAction(){
  // Holen Sie sich den vom Anwendungsprogramm verwendeten Cache
  $cache = $this->getCache(); 

  // Holen Sie sich den Index Service-Client und das Modell
  $indexServiceClient = new IndexServiceClient($this->getConfig());
  $indexModel = $this->_helper->ModelLoader->load('admin_indexmodel', $cache);
  $indexModel->setIndexServiceClient($indexServiceClient);

  // Laden Sie alle Indizes
  $indexes = $indexModel->loadIndexes();

  $this->view->assign('indexes', $indexes);
}

Zur Zeit habe ich einen sehr einfachen Testfall:-

public function testIndexActionRoute() {
  $this->dispatch( '/admin/index' );
  $this->assertModule('admin', 'Falsches Modul verwendet');
  $this->assertController('index', 'Falscher Controller verwendet');
  $this->assertAction('index', 'Falsche Aktion verwendet');
}

Dieser Test funktioniert, ruft jedoch die echten Modelle und Dienste auf, was manchmal dazu führt, dass es auf der Testumgebung Zeitüberschreitungen gibt und fehlschlägt. Um nur den Controller ordnungsgemäß zu testen, benötige ich Mocks und Erwartungen für IndexServiceClient und IndexModel - wie wird das gemacht?

4voto

Alex N. Punkte 13269

Nun, da ich hier nicht viele Antworten sehe, werde ich versuchen, meine Meinung hinzuzufügen (potenziell diskutierbar). Die unten stehende Antwort ist meiner Meinung nach sehr subjektiv (und ich denke nicht sehr nützlich, aber hier sind wir trotzdem).

Ich denke, Controller sind nicht gut für Unittests geeignet. Ihre Geschäftslogikschicht, Modelle usw. sind das, was testbar ist. Controller sind mit der Benutzeroberfläche verbunden und bringen das System gewissermaßen zusammen - daher sind sie meiner Meinung nach besser für Integrations- und UI-Tests geeignet - etwas, das Pakete wie Selenium verwendet werden.

Meiner Meinung nach sollte das Testen einfach genug sein, um umsetzbar zu sein, sodass der Gesamtaufwand für die Testimplementierung angemessen ist. Das Verdrahten aller Abhängigkeiten für einen Controller scheint mir (mit meinem begrenzten Wissen natürlich) eine etwas zu große Aufgabe zu sein.

Die andere Möglichkeit ist zu überlegen, was tatsächlich in Ihren Controllern passiert. Wiederum, meiner Meinung nach soll es in erster Linie auf Klebeebene zwischen Ihrer Geschäftslogik und Ihrer Benutzeroberfläche sein. Wenn Sie viel Geschäftslogik in den Controller einfügen, wird dies sich negativ auswirken (zum Beispiel wird es nicht leicht testbar sein..).

All dies ist natürlich eher theoretisch. Hoffentlich kann jemand eine bessere Antwort liefern und tatsächlich zeigen, wie man einen Controller einfach für Unittests verdrahtet!

2voto

Mathew Attlee Punkte 549

Eine mögliche Lösung, die ein Kollege vorgeschlagen hat, besteht darin, einen Zend Controller Action Helper zu verwenden, um Mock-Abhängigkeiten einzufügen. Dies sollte in der Theorie funktionieren, aber ich habe diese Methode noch nicht umfassend getestet.

Hier ist ein Beispiel dafür, es auf diese Weise zu tun.

class Mock_IndexModel_Helper extends Zend_Controller_Action_Helper_Abstract {

    private $model;

    public function __construct($model) {
        $this->model = $model;
    }   

    /**
     * Init-Hook
     */
    public function init() {            
        $this->getActionController()->setIndexModel( $this->model );
    }

}

class IndexControllerTest extends Zend_Test_PHPUnit_ControllerTestCase {

    public $bootstrap = BOOTSTRAP;

    public function setUp(){
        parent::setUp();
    }

    /**
    * Testen, ob das richtige Modul/Controller/Aktion verwendet werden
    */
    public function testIndexAction() {                 
        $mockIndexModel = $this->getMock("IndexModel");

        Zend_Controller_Action_HelperBroker::addHelper(new Mock_IndexModel_Helper($mockIndexModel));

        $this->dispatch( '/admin/index' );

        $this->assertModule('admin', 'Falsches Modul verwendet');
        $this->assertController('index', 'Falscher Controller verwendet');
        $this->assertAction('index', 'Falsche Aktion verwendet');
    }    
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X