我们使用Varien_Http_Client
从Magento扩展程序发出http请求,如下所示:
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;
}
我知道我应该避免测试Varien_Http_Client
的内部;相反,我应该测试我们正在向它发送正确的输入,并正确处理其输出。我可以很容易地模拟Varien_Http_Client
,但即使我重构这段代码让我用它的模拟替换Varien_Http_Client
,我也不明白如何通常*测试构造函数是否被预期调用参数,因为构造函数由PHPUnit::getMock
调用。
我不需要模拟对象;我需要一个模拟类。如何测试使用预期参数调用构造函数?
*(在这种情况下,我知道如何解决特定于Varien_Http_Client
的此问题,但我可以使用更多不透明的第三方代码做什么?)
答案 0 :(得分:3)
这就是我们所谓的“不可测试”代码。在方法中构建依赖项时,无法模拟它们。在模型中每次使用“new”关键字都是一个信号,您应该考虑注入对象而不是在其中创建它。在我看来,该规则的唯一例外是当您创建“数据容器”对象或工厂类时。但在这些情况下,您可以测试对象,因为方法会返回它。
正如您所说,您展示的方法需要一些重构,例如:
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');
(...)
最佳!