2017-03-16 2 views
0

Seit ich Zend Framework 3 benutze, hatte ich Probleme mit dem Testen meiner Controller. Ich versuche, meine Controller mit PhpUnit 5.7 zu testen, und meine Controller hängen von Zend Form ab, das mit DoctrineObject von Doctrine hydratisiert wird.
Ich versuche, dies so einfach wie möglich zu setzen, also hier ein minimales Beispiel für ein Setup das mir geben Kopfschmerzen:Schreiben Tests für Controller mit Formularen

Controller:

class IndexController extends AbstractActionController { 
    private $form; 
    public function __construct(AlbumForm $form) { 
     $this->form = $form; 
    } 
    public function indexAction() { 
     return ['form' => $this-form]; 
    } 
} 

Controller:

class IndexControllerFactory implements FactoryInterface { 
    public function __invoke(ContainerInterface $container, ...) { 
     $formManager = $container->get('FormElementManager'); 
     return new IndexController($formManager->get(AlbumForm::class)); 
    } 
} 

Der entsprechende Ansichtsvorlage in albums/index/index.phtml:

<?php 
$this->form->prepare(); 
$this->form->setAttribute('action', $this->url(null, [], true)); 

$albumFieldset = $this->form->get('album'); 
?> 
<?= $this->form()->openTag($this-form) ?> 
    <div class="form-group"> 
     <?= $this->formRow($albumFieldset->get('name')) ?> 
    </div> 
<?= $this->form()->closeTag() ?> 

Die Form:

class AlbumForm extends Form { 
    public function init() { 
     $this->add([ 
      'name' => 'albumFieldset', 
      'type' => AlbumFieldset::class, 
      'options' => [ 
       'use_as_base_fieldset' => true, 
      ], 
     ]); 
    } 
} 

Die Fieldset:

class AlbumFieldset extends Fieldset { 
    public function init() { 
     $this->add([ 
      'name' => 'name', 
      'type' => Text::class, 
      'options' => [ 
       'label' => 'Name of album', 
      ], 
     ]); 
    } 
} 

Die FieldsetFactory:

class AlbumFieldsetFactory implements FactoryInterface { 
    public function __invoke(ContainerInterface $container, ...) { 
     $objectManager = $container->get(ObjectManager::class); 
     $fieldset = new AlbumFieldset(); 
     $fieldset->setHydrator(new DoctrineObject($objectManager)); 
     $fieldset->setObject(new Album()); 
     return $fieldset; 
    } 
} 

Nun, so weit alles funktioniert super.
Allerdings, wenn ich Tests für dieses schreibe, laufe ich in Schwierigkeiten. Lassen Sie mich Ihnen zuerst zeigen, was ich bisher habe:

Dies wird schließlich ohne Fehler ausgeführt werden. Ich möchte Sie jedoch auf die letzten Methoden aufmerksam machen, insbesondere auf mockName(). Die meisten dieser Definitionen sind vollständig voreingestellt und fast keiner von ihnen ist in AlbumFieldset am Anfang angegeben (nur Name ist). Es ist sehr ärgerlich, sie für jede Formulareingabe zu schreiben, die ich haben kann, und das Schreiben dieses Downs führt tatsächlich mehr Fehler ein, als es löst. Zum Beispiel bin ich mir immer noch nicht sicher, was die richtige Label-Option für wäre. Ich interessiere mich eigentlich nicht einmal für diese Option, aber ich muss etwas in meinem Test darüber schreiben, weil sonst der Test mit 'Prophecy\Exception\Call\UnexpectedCallException' with message 'Method call: - getLabelOption("always_wrap") on Double\Zend\Form\Element\Text\P245 was not expected, expected calls were: ... fehlschlägt.

Daher frage ich Sie: Gibt es einen besseren Weg, um darüber zu gehen? Ein Weg, der nicht mehr als 20 Zeilen für jedes Feld in meinem Fieldset enthält. Wenn es darum geht, meine Controller/Fieldsets/View Templates (etc.) neu zu schreiben, wäre das völlig in Ordnung!

Jede Hilfe wird sehr geschätzt! Es ist auch das erste Mal, dass ich etwas in einem Forum in über acht Jahren Programmierung anfragesuche, also bitte, wenn etwas unklar ist.

Yours Steffen

PS: Was habe ich schon versucht, die IndexController null anstelle einer tatsächlichen Form zu geben und einfach die Aussicht Vorlage abbrechen, wenn es erkennt, dass die Form null ist. Obwohl das ohne diese Konfiguration funktionierte, habe ich im Grunde nur die Logik der Ansichtsvorlage vermieden. Aus diesem Grund konnte ich Fehler in der Ansichtsvorlage nicht erkennen. Das ist nicht was ich will.

Antwort

0

edit IndexControllerTest: Ändern Sie privat als geschützt anderswo und erweitert es für Ihre neuen Felder. Jeder neue Controller muss Methoden überschreiben, die parent :: methodname ($ args) aufrufen und den benötigten Code hinzufügen ...

Verwandte Themen