Lors de l'écriture de tests unitaires, il est parfois nécessaire de modifier les objets Magento. PHPunit propose plusieurs solutions, comme par exemple l'utilisation des
objets simulacres (mock objects). Cependant, leur mise en oeuvre peut parfois être lourde. Nous allons voir ici comment détourner le fonctionnement transactionnel de Magento pour réaliser nos tests.
Contexte
Deux attributs ont été ajoutés aux produits Magento : une date de début et une date de fin.
Si les dates sont spécifiées, le produit ne doit être visible que dans l'intervalle défini. Les bornes sont incluses.
Parmi les tests effectués, on souhaite s'assurer qu'une collection contiendra bien un produit du jour.
Code
Dans la fonction setUp du test unitaire, on signale explicitement que l'on démarre une transaction.
<?php
protected function setUp()
{
Mage::getSingleton('core/resource')->getConnection('core_write')->beginTransaction();
}
?>
Dans la fonction de clôture du test, on va annuler toutes les transactions.
<?php
protected function tearDown()
{
Mage::getSingleton('core/resource')->getConnection('core_write')->rollback();
}
?>
Testons si un produit ayant la date du jour est bien renvoyé par la collection modifiée.
<?php
public function testaddActivationFilterDateToday()
{
//On récupère le premier produit sans aucun filtre
$validProduct = Mage::getResourceModel('catalog/product_collection')->load()->getFirstItem();
$today = date('Y-m-d 00:00:00');
//on lui affecte la date (les bornes sont incluses dans notre cas)
$validProduct->setData('date_activation', $today);
$validProduct->setData('date_desactivation', $today);
//on enregistre le produit
$validProduct->save();
//Notre méthode de test est sur un événement
$event = new Varien_Event();
$event->setName('catalog_product_collection_load_before');
$collection = Mage::getResourceModel('catalog/product_collection');
$event->setCollection($collection);
$observer = new Varien_Event_Observer();
$observer->setData(array('event' => $event));
//on filtre la collection avec notre méthode
$this->object->addActivationFilter($observer);
//La collection doit être filtrée correctement
$product = $collection->getFirstItem();
//Le premier produit renvoyé doit être notre produit
$this->assertEquals($product->getId(), $validProduct->getId());
}
?>
Conclusion
Grâce au mode transactionnel utilisé par Magento, nous avons pu mettre en oeuvre facilement notre test.
Bien sûr, nous sommes partis du postulat que notre base de données d'intégration contenait au moins un produit.
Le cas échéant, notre plate-forme d'intégration continue nous remontera une erreur. Nous verrons alors comment améliorer
notre méthodologie de tests.