###Dependency Injection makes your code easier to test.
Dependency Injection makes your code easier to test.
I learned this first-hand when I was tasked with fixing a hard-to-catch bug in Magento's PayPal integration.
An issue would arise when PayPal was telling Magento about a failed payment: Magento wouldn't register the failure properly.
Testing a potential fix "manually" would be very tedious: you'd need to somehow trigger a "Failed" PayPal notification. You'd have to submit an e-check, cancel it, and wait for it to error out. That means 3+ days to test a one-character code change!
Luckily, it appears that the Magento core devs who developed this function had testing in mind, and used a dependency injection pattern to make it trivial. This allows us to verify our work with a simple test case like this one:
<?php
// This is the dependency we will inject to facilitate our testing
class MockHttpClient extends Varien_Http_Adapter_Curl {
function read() {
// Make Magento think that PayPal said "VERIFIED", no matter what they actually said...
return "HTTP/1.1 200 OK\n\nVERIFIED";
}
}
// Here, we trick Magento into thinking PayPal actually sent something back.
// Magento will try to verify it against PayPal's API though, and since it's fake data, it'll always fail.
$ipnPayload = array (
'invoice' => '100058137', // Order ID to test against
'txn_id' => '04S87540L2309371A', // Test PayPal transaction ID
'payment_status' => 'Failed' // New payment status that Magento should ingest
);
// This is what Magento's controller calls during a normal IPN request.
// Instead of letting Magento talk to PayPal, we "inject" our fake HTTP client, which always returns VERIFIED.
Mage::getModel('paypal/ipn')->processIpnRequest($ipnPayload, new MockHttpClient());
I'm sure the DI pattern has plenty of other advantages, but increased testability is the single biggest benefit in my mind.
If you're curious about the solution to this problem, check out the GitHub repo here: https://github.com/bubbleupdev/BUCorefix_Paypalstatus