Während wir die Unit-Tests für unsere neue Erweiterung EmailImages geschrieben haben, mussten wir feststellen, dass es in Ecomdev_PHPUnit keinen einfachen Weg (zumindest keinen dokumentierten) gab, um die Nutzung des Caches zu aktivieren. Es schien nur ohne aktivierten Cache zu funktionieren. Da unser Modul Bilder cachet, die heruntergeladen werden, um sie an eine E-Mail anzuhängen, wollten wir mit dem Unit-Test mindestens 100% Code-Coverage erreichen und in der Logdatei sehen, dass der Cache für diese Bilder tatsächlich verwendet wird. (Natürlich wäre es besser, diesen Teil ebenfalls in den Unit-Test aufzunehmen, aber das überlassen wir dem Leser als Übung — Beiträge willkommen!)
Glücklicherweise hatten wir bereits unseren eigenen Cache-Typ definiert und herausgefunden, dass wir die folgende Methode aufrufen müssen (definiert in Zeile 466 in app/code/core/Mage/Core/Model/Cache.php), um zu bestimmen, ob der Cache zum Lesen oder Schreiben verfügbar ist:
Mage_Core_Model_Cache::canUse( $typeCode )
oder auch
Mage::getModel('core/cache')->canUse($typeCode);
Letztendlich war die Lösung also relativ einfach:
- ein Mock-Modell für Mage_Core_Model_Cache erstellen, um die Funktion canUse() zu ersetzen
- die Funktion canUse() durch unsere Implementierung ersetzen, die true zurückgibt, wenn:
- unsere Erweiterung aktiviert ist
- der mitgelieferte Cache-Typ in $typeCode unser Cache-Typ ist
- das ursprüngliche Modell 'core/cache' durch unser Mock-Objekt ersetzen
Da wir die Ersatzfunktion auch dafür verwenden zu prüfen, ob etwas passiert, wenn unsere Erweiterung in der Konfiguration deaktiviert ist, haben wir alles in einer einfach zu verwendenden geschützten Methode untergebracht:
/**
* Run addImages() with Mage_Core_Model_Cache::canUse() overriden.
*/
protected function _overrideCacheCanUse()
{
$mock = $this->getModelMock('core/cache', array('canUse'));
$mock->expects($this->any())
->method('canUse')
->will($this->returnCallback(array($this, 'Mage_Core_Model_Cache_canUse')));
$this->replaceByMock('model', 'core/cache', $mock);
}
Wie Sie sehen, haben wir die Methode canUse() durch unsere eigene Methode Mage_Core_Model_Cache_canUse() ersetzt:
/**
* Mage_Core_Model_Cache function canUse() replacement function.
*
* @param string $typeCode
* @return boolean
*
* @see addImagesCache(), addImagesDisabled(), addImagesException(),
* Mage_Core_Model_Cache::canUse()
*/
public function Mage_Core_Model_Cache_canUse( $typeCode )
{
if ( Mage::getStoreConfig('system/emailimages/enable') )
{
if ( Mage::getStoreConfig('test/emailimages/use_cache') )
{
if ( Magentron_EmailImages_Helper_Data::CACHE_TYPE == $typeCode )
{
return true;
}
}
return false;
}
Jetzt müssen wir nur noch unsere Methode _overrideCacheCanUse() aufrufen, um die Cache-Nutzung für einige unserer Tests zu aktivieren. In diesem Fall hatten wir bereits eine Funktion, die testete, ob das Hinzufügen von Bildern tatsächlich funktioniert. Wir rufen einfach beide Funktionen auf, sodass dieselben Tests durchgeführt werden, jetzt aber mit aktiviertem Cache:
/**
* Test addImages() with cache turned on
*
* @test
* @loadFixture
* @doNotIndexAll
*/
public function addImagesCache()
{
$this->_overrideCacheCanUse();
$this->addImages();
}
Natürlich ist das vielleicht nicht der sauberste Weg, um einen Unit-Test zu erstellen, der prüft, ob der Cache richtig genutzt wird, aber für uns war es genau das, was wir brauchten, um sicherzustellen, dass unser gesamter Code mindestens einmal ausgeführt wird.
Hoffentlich konnten wir Ihnen zeigen, wie schön und einfach Sie Mock-Objekte mit Ecomdev_PHPUnit verwenden können. Viel Erfolg mit Ihren eigenen PHPUnit-Tests!