Reputation: 77167
We use Varien_Http_Client
to make http requests from a Magento extension, like this:
public function callApi(…)
{
<SNIP>
// Set default factory adapter to socket in case curl isn't installed.
$client = new Varien_Http_Client($apiUri, array(
'adapter' => 'Zend_Http_Client_Adapter_Socket',
'timeout' => $timeout,
));
$client->setRawData($xmlDoc->saveXML())->setEncType('text/xml');
$response = $client->request($method);
$results = '';
if ($response->isSuccessful()) {
$results = $response->getBody();
}
return $results;
}
I understand I should avoid testing the internals of Varien_Http_Client
; rather, I should test that we are sending it the right inputs, and handling its outputs correctly. I can mock Varien_Http_Client
easily enough, but even if I refactor this code to let me replace the Varien_Http_Client
with its mock, I don't understand how to generally* test that the constructor was called with the expected arguments, since the constructor is called by PHPUnit::getMock
.
I don't need a mock object; I need a mock class. How can I test that a constructor was called with expected arguments?
* (In this case I know ways to work around this problem specific to Varien_Http_Client
, but what can I do with more opaque third-party code?)
Upvotes: 5
Views: 2646
Reputation: 11374
This is what we call "untestable" code. When you build dependencies inside your methods, there is no way to mock them. Every use of "new" keyword in your model is a signal that you should consider injecting the object instead of create it inside. In my opinion, the only exception from that rule is when you create a "data container" object or factory class. But in these cases probably you can test the object because methods will return it.
So as you said, the method you showed need a little refactor, for example:
class ApiClass
{
protected $client;
public function __construct(Varien_Http_Client $client)
{
$this->client = $client;
}
public function callApi()
{
$this->client->setRawData($xmlDoc->saveXML())->setEncType('text/xml');
(...)
Best!
Upvotes: 4