tak*_*hin 6 phpunit unit-testing zend-framework mocking google-api
我有以下方法,可从Google Analytics检索热门访问过的网页:
public function getData($limit = 10)
{
$ids = '12345';
$dateFrom = '2011-01-01';
$dateTo = date('Y-m-d');
// Google Analytics credentials
$mail = 'my_mail';
$pass = 'my_pass';
$clientLogin = Zend_Gdata_ClientLogin::getHttpClient($mail, $pass, "analytics");
$client = new Zend_Gdata($clientLogin);
$reportURL = 'https://www.google.com/analytics/feeds/data?';
$params = array(
'ids' => 'ga:' . $ids,
'dimensions' => 'ga:pagePath,ga:pageTitle',
'metrics' => 'ga:visitors',
'sort' => '-ga:visitors',
'start-date' => $dateFrom,
'end-date' => $dateTo,
'max-results' => $limit
);
$query = http_build_query($params, '');
$reportURL .= $query;
$results = $client->getFeed($reportURL);
$xml = $results->getXML();
Zend_Feed::lookupNamespace('default');
$feed = new Zend_Feed_Atom(null, $xml);
$top = array();
foreach ($feed as $entry) {
$page['visitors'] = (int) $entry->metric->getDOM()->getAttribute('value');
$page['url'] = $entry->dimension[0]->getDOM()->getAttribute('value');
$page['title'] = $entry->dimension[1]->getDOM()->getAttribute('value');
$top[] = $page;
}
return $top;
}
Run Code Online (Sandbox Code Playgroud)
它肯定需要一些重构,但问题是:
据我了解,通常您会希望将依赖项(Google客户端对象)注入受测系统(SUT,包含该getData()方法的类).
我总是看到专家使用构造函数注入 - 我确信它是一种更好的方法,因为它可以在前面清楚地识别依赖关系.但是,说实话,我似乎永远不能设计好我的物品,以便始终做到这一点.所以我最终做了setter注入.
像这样的东西:
public function getClient()
{
if (null === $this->_client){
// $mail and $pass are stored somewhere, right?
$clientLogin = Zend_Gdata_ClientLogin::getHttpClient($mail, $pass, "analytics");
$this->_client = new Zend_Gdata($clientLogin);
}
return $this->_client;
}
public function setClient($client)
{
$this->_client = $client;
return $this;
}
Run Code Online (Sandbox Code Playgroud)
然后在单元测试中,您创建一个$client对象作为您的实时模拟$client,设置期望,然后使用上述setClient($client)方法将其注入您的SUT .
明白了吗?
David Weinraub 向您介绍了前半部分(如何将您的类设置为可模拟的),所以我将介绍后半部分(如何构建模拟)。
PHPUnit 通过简单的 API 提供了强大的模拟工具。在我的书中,传递用户和密码太简单了,无法进行测试,因此我只会模拟查询和结果的处理。这需要 Zend_Gdata 和 Zend_Gdata_App_Feed 的模拟。
public function testGetData() {
// expected input to and output from mocks
$url = 'https://www.google.com/analytics/feeds/data?ids=ga:12345...';
$xml = <<<XML
<feed>
...
</feed>
XML;
// setup the mocks and method expectations
$client = $this->getMock('Zend_Gdata', array('getFeed'));
$feed = $this->getMock('Zend_Gdata_App_Feed', array('getXML'));
$client->expects($this->once())
->method('getFeed')
->with($url)
->will($this->returnValue($feed));
$feed->expects($this->once())
->method('getXML')
->will($this->returnValue($xml));
// create the report (SUT) and call the method being tested
$report = new MyReport();
$report->setClient($client);
$top = $report->getData();
// check the final output; mocks are verified automatically
$this->assertEquals(10, count($top));
$this->assertEquals(array(
'visitors' => 123,
'url' => 'http://...',
'title' => 'My Home Page'
), $top[0]);
}
Run Code Online (Sandbox Code Playgroud)
上面的代码将测试 URL 是否正确并返回 Google 期望的 XML 提要。它消除了对 Zend_Gdata 类的所有依赖。如果您不在 setClient() 上使用类型提示,您甚至可以使用 stdClass 作为两个模拟的基础,因为您将只使用模拟方法。
| 归档时间: |
|
| 查看次数: |
1888 次 |
| 最近记录: |