Enable cache for Ecomdev_PHPUnit

Posted on Mon July 4, 2011 by Jeroen Derks There have been 1 comment(s)

While writing the unit tests for our new extension EmailImages we discovered that there was no easy way in Ecomdev_PHPUnit (or at least no documented way) to enable the use of the cache. It seemed it would only work without the cache enabled. Since our module caches images that were downloaded to be attached to an email, we would like to at least use the unit test to get 100% code coverage and to see in the log file that the cache was actually being used for these images. (Of course it would be better to have that part included in the unit test itself, but we'll leave that as an exercise to the reader, please submit your input!)

Luckily, we had defined our own cache type and discovered that we would have to call the following method (defined in line 466 in app/code/core/Mage/Core/Model/Cache.php) to determine whether the cache is available for reading from or writing to:

Mage_Core_Model_Cache::canUse( $typeCode )
a.k.a.
Mage::getModel('core/cache')->canUse($typeCode);

So, in the end solution turned out to be relatively simple:

  1. create a mock model for Mage_Core_Model_Cache to replace function canUse()
  2. replace function canUse() with our implementation, returning true if:
    1. our extension is enabled
    2. the supplied cache type in $typeCode is our cache type
  3. replace the original 'core/cache' model with our mock object

Since we are using the replacement function also for checking whether anything happens when our extension has effectively been disabled in the configuration, we put everything in an easy to use supporting protected method:

	/**
	 *	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);
	}

As you can see we have replaced the canUse() method with our own method Mage_Core_Model_Cache_canUse():

	/**
	 *	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;
	}

Now all we need to do is call our _overrideCacheCanUse() method to enable use of the cache for some of our tests. In this case we already had a function that would test whether adding images actually works. We simply call both functions so that the same tests are performed but now with the use of the cache enabled:

	/**
	 *	Test addImages() with cache turned on
	 *
	 *	@test
	 *	@loadFixture
	 *	@doNotIndexAll
	 */
	public function addImagesCache()
	{
		$this->_overrideCacheCanUse();

		$this->addImages();
	}

Of course, this might not be the cleanest way to create a unit test for checking whether the cache is being used properly, but for us this was exactly what we needed to make sure that all our code was run at least once.

Hopefully, we have been able to show you how nice and easy you can use mock objects with Ecomdev_PHPUnit. Good luck with your own PHPUnit tests!


This post was posted in Magento, Development

1 Response to Enable cache for Ecomdev_PHPUnit

  • I tried this solution, but it was not good enough for me, because I wanted to use Mage::app()->useCache(...) for checking cache status and Mage::app() is instantiated before replacement is defined.

    After further investigation I found out that it is not so hard to change cache status for testing. Mage_Core_Model_App is replaced during testing execution by EcomDev_PHPUnit_Model_App and this class provides method setCacheOptions.

    So forcing cache to be enabled during test is really simple:
    $cacheOptions = Mage::app()->getCacheOptions();
    $cacheOptions['cache_do_be_enabled'] = 1;
    Mage::app()->setCacheOptions($cacheOptions);

    I hopefuly this will help somebody.

    Posted on Thu August 15, 2013 at 17:13

Comments