[CakePHP] Constructor im AppController verwenden

In den beiden vorherigen Artikeln (Artikel 1 / Artikel 2) habe ich über die Möglichkeiten zum Testen von Controllern geschrieben, welche die Klasse CakeEmail verwenden. Leider traten damit Probleme auf, sobald ich die wunderbare Welt des Entwicklers und der Testumgebung verlassen habe und die Applikation als solches habe laufen lassen.

Im ersten Artikel habe ich erwähnt, dass die Deklaration der protected-Variable $email und ihrer Definition im Konstruktor der Klasse AppController erfolgen kann. Leider stimmt das so nicht. Es ergeben sich nur Probleme, wenn die Klasse AppController einen Konstruktor enthält. Der folgende Aufruf lässt die Applikation nicht mehr starten:

App:Uses('Controller', 'Controller');

class AppController extends Controller
{
    public function __construct()
    {
        parent::construct();
        // Some more code or not, it doesn't matter
    }
}

Um ein Verhalten zu bekommen, dass der Erwartung des oben gezeigten nahe kommt, soll auf die Erstellung eines Konstruktors in der Klasse AppController verzichtet werden und stattdessen die Methode beforeFilter() überschrieben werden (Quelle leider verloren 🙁 )

Auf jeden Fall funktionieren meine Tests dadurch nicht mehr. Die einzige Abhilfe ist das Verschieben der $email-Variable und des Konstruktors von der AppController-Klasse in jede Klasse, in der die CakeEmail-Klasse verwendet wird.


class UsersController extends AppController
{
    protected $email;

    public function __construct()
    {
        parent::__construct();
        $this->email = new CakeEmail('gmail');
    }
...

Ein Problem bestand aber weiterhin: Durch die Verwendung von „Fluent Interface“ in PHPUnit wird im Fall von komplett gemockten CakeEmail-Objekten (siehe Artikel 2) erwartet, dass Aufrufe wie z.B.

to()

oder

subject()

eine Referenz auf das Objekt selber zurückgeben. Wir nun ein CakeEmail-Objekt gemockt

$Users->email = $this->getMock('CakeEmail');

gibt die erste aufgerufene Methode im Controller nichts zurück und der Aufruf der zweiten Methode schlägt mit einer Exception fehl.

Um dieses Problem zu lösen müssen entweder alle Rückgabewerte alle verwendeten Aufrufe im Test überschrieben werden (argh, gibt das viel zu tun), oder aber es wird nur die Methode ’send‘ der CakeEmail-Klasse gemockt:

$Users->email = $this->getMock('CakeEmail', array('send'));

$Users->email
    ->expects($this->once())
    ->method('send');

Ich hoffe, ich konnte Eure Probleme dadurch lösen!


Beitrag veröffentlicht

in

von

Schlagwörter:

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert