2

So I'm working on some tests where I need to create fixtures data.

Basically I used to have the following pseudo code that worked fine:

public function setUp()
{
    // Programmatically create a coupon code
}

// Test methods

public function tearDown()
{
    // Programmatically delete the coupon code
}

On Vinai's recommendation, and to make my test easier to manage I decided to change that code to the following so I don't have to manually delete my fixture data anymore:

public function setUp()
{
    Mage::getSingleton('core/resource')->getConnection('core_write')->beginTransaction();
    // Programmatically create a coupon code
}

// Test methods

public function tearDown()
{
    Mage::getSingleton('core/resource')->getConnection('core_write')->rollBack();
}

However, with this code, my tests don't run properly anymore and I get the Zend_Db_Statement_Exception: SQLSTATE[23000]: Integrity constraint violation errors.

I was wondering if that's the right way of using transaction ?

Is the following order the right one ?

  • begin transaction
  • make DB changes (create DB data, and call the save() method)
  • rollback transaction

Do I need to call commit() before rollBack() ?

1 Answer 1

4

I would have to see the code you are using. All DB operations that do not change the structure of tables (so no DDL methods) are allowed in a transaction.

All I can offer is the following example of a test that utilizes a transaction to isolate the database changes.

<?php

namespace Example;

class SomeTestWithATransaction extends \PHPUnit_Framework_TestCase
{
    /**
     * @return \Varien_Db_Adapter_Interface
     */
    private function getConnection()
    {
        /** @var \Mage_Core_Model_Resource $resource */
        $resource = \Mage::getSingleton('core/resource');
        return $resource->getConnection('default_write');
    }

    /**
     * @param string $sku
     * @return \Mage_Catalog_Model_Product
     */
    private function createProduct($sku)
    {
        $prevStore = \Mage::app()->getStore();
        \Mage::app()->setCurrentStore(\Mage_Core_Model_Store::ADMIN_CODE);
        $product = $this->instantiateProductModel($sku);
        $product->save();
        \Mage::app()->setCurrentStore($prevStore->getCode());

        return $product;
    }

    /**
     * @param string $sku
     * @return \Mage_Catalog_Model_Product
     */
    private function instantiateProductModel($sku)
    {
        /** @var \Mage_Catalog_Model_Product $product */
        $product = \Mage::getModel('catalog/product');
        $product->setData([
            'sku'              => $sku,
            'name'             => 'Test Product ' . $sku,
            'price'            => '1.0',
            'weight'           => '1',
            'type_id'          => \Mage_Catalog_Model_Product_Type::TYPE_SIMPLE,
            'attribute_set_id' => $this->getAttributeSetId(),
            'website_ids'      => array_keys(\Mage::app()->getWebsites()),
        ]);
        $this->addTestStockItemToProduct($product);
        return $product;
    }

    /**
     * @return string
     */
    private function getAttributeSetId()
    {
        /** @var \Mage_Eav_Model_Config $eavConfig */
        $eavConfig = \Mage::getSingleton('eav/config');
        $productEntityType = $eavConfig->getEntityType(\Mage_Catalog_Model_Product::ENTITY);
        return $productEntityType->getDefaultAttributeSetId();
    }

    private function addTestStockItemToProduct(\Mage_Catalog_Model_Product $product)
    {
        /** @var \Mage_CatalogInventory_Model_Stock_Item $stockItem */
        $stockItem = \Mage::getModel('cataloginventory/stock_item');
        $stockItem->setQty(1000);
        $stockItem->setIsInStock(1);
        $product->setData('stock_item', $stockItem);
    }

    protected function setUp()
    {
        $this->getConnection()->beginTransaction();
        \Mage::app()->loadArea(\Mage_Core_Model_App_Area::AREA_FRONTEND);
    }

    protected function tearDown()
    {
        $this->getConnection()->rollBack();

        \Mage::reset();
    }

    public function testUpdatesTheProductInTheDatabase()
    {
        \Mage::app()->setCurrentStore(\Mage_Core_Model_Store::ADMIN_CODE);

        $product = $this->createProduct('foo');
        $id = $product->getId();
        $product->setData('sku', 'bar');
        $product->save();

        /** @var \Mage_Catalog_Model_Product $product2 */
        $product2 = \Mage::getModel('catalog/product');
        $product2->load($id);

        $this->assertSame('bar', $product2->getSku());
    }

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.