unit-testing - 如何对 Google API 的调用进行单元测试

标签 unit-testing zend-framework mocking phpunit 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;
}

它肯定需要一些重构,但问题是:
  • 你会如何为这个方法编写 PHPUnit 测试?
  • 最佳答案

    据我了解,通常您希望将依赖项(Google 客户端对象)注入(inject)到被测系统(SUT,包含 getData() 方法的类)中。

    我总是看到专家们使用构造函数注入(inject)——我相信这是一种更好的方法,因为它可以清楚地预先识别依赖关系。但是,说实话,我似乎永远无法将我的对象设计得足够好,以至于总能做到这一点。所以我最终使用了 setter 注入(inject)。

    像这样的东西:

    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;
    }
    

    然后在单元测试中,创建一个 $client对象作为您现场的模拟$client ,设置期望值,然后使用 setClient($client) 将其注入(inject)您的 SUT上述方法。

    明白了吗?

    关于unit-testing - 如何对 Google API 的调用进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4850452/

    相关文章:

    javascript - Jest |测试 moment 函数是否被调用以及返回输出是否正确

    zend-framework - Zend Framework - 从 Bootstrap 获取前端 Controller ?

    php - 使用 Zend TableGateway 的 select() 时无法检索 id 值

    java - 如何重写模拟对象的函数?

    java - 什么 Maven Artefact 持有 PowerMock.mockStaticPartial?

    javascript - 如何使用 Jest 和 Enzyme 在 React 中模拟 <AppContext.Consumer>

    php - 测试 Guzzle 6 下载进度

    sql - ZF 子查询问题

    python - mock.patch 的正确路径

    unit-testing - 如何对 ActionFilterAttribute 进行单元测试