Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Magento/PHPUnit - force an exception

I'm using phpunit and the ecomdev module to unit test Magento. For a particular class the last code that needs to be tested is an exception on attempting to save a model in a try/catch. The only way I can see to get to the exception is alter the database temporarily. So I changed the table name which works, but then I have to name it back. If the test itself fails I'm in an inconsistent state.

I'd really like to get that code tested so the coverage is 100%. Otherwise I'll be wondering why it's 98% until I look at the code and remember the exception isn't tested.

I was trying to close the connection but I need it to log the exception. So I'm wondering if maybe there is something I can temporarily do to the model or resource model to cause the save to raise an exception. Something that would be reset on the next load.

One note - I can't see anyway that manipulating data will cause the exception. Again the only scenario I see causing an exception in production is if the database connection goes away.

Any ideas?

Edit: Sample Code:

public function logStuff($stuff){

    try{
        Mage::getModel('my/stuff')
            ->setData('stuff', $stuff)
            ->save();

    }catch(Exception $e){
        Mage::helper('log/error')->logError(__METHOD__, "Could not save stuff: ". $e->getMessage());
    }
}
like image 971
gwgeller Avatar asked Mar 12 '26 18:03

gwgeller


1 Answers

To make test the exception catch, you need to replace your model instance with the mocked one. It is very easy to achieve with EcomDev_PHPUnit extension:

$mockedStuff = $this->getModelMock('your/stuff', array('save'));
$mockedStuff->expects($this->once()) // How many times it is invoked
     ->method('save') // Wich method to mock
     ->will($this->returnCallback(function () {
          throw new Exception('Some error text');
     })); // Your exception

$this->replaceByMock('model', 'your/stuff', $mockedStuff);

Also you can evaluate your logging stuff by using mock as well.

$loggerMock = $this->getHelperMock('log/error', array('logError'));
$loggerMock->expects($this->once())
    ->method('logError')
    ->with('className::methodName', 'Could not save stuff: Some error text'); // Check that correct arguments passed

$this->replaceByMock('helper', 'log/error', $loggerMock);

Have fun with unit tests :)

like image 72
Ivan Chepurnyi Avatar answered Mar 14 '26 08:03

Ivan Chepurnyi