Как проверить вход в систему с помощью openid в Zend Framework? - PullRequest
9 голосов
/ 10 марта 2011

Я зарегистрировался на моем веб-сайте в ZF с помощью openid (например, с помощью Google, Myopenid, Yahoo). Работает хорошо. Но я не знаю, как написать для него модульный тест.

В качестве примера я хотел бы написать модульные тесты:

public function testUserLogsSuccessfullyUsingGoogle() {
        // don't know how to dispach/mock that my action
        // will take a user to google, and google will
        // return authentication data (e.g. email)
        // Once user is authenticated by google, 
        // I make Zend_Auth for the user. 
        // 


        $this->asertTrue(Zend_Auth::getInstance()->getIdentity());
}


public function testUserLogsUnSuccessfullyUsingGoogle() {
        // don't know how to dispach/mock that my action
        // will take a user to google, and USER WILL NOT ALLOW
        // for authentication. Then off course I don't make
        // Zend_Auth for the user. 
        // 


        $this->asertFalse(Zend_Auth::getInstance()->getIdentity());
}

Кто-нибудь знает, как издеваться над этим сценарием? Может быть, у кого-нибудь есть пример?

1 Ответ

1 голос
/ 11 марта 2011

Вам не нужно проверять, что Google работает и отвечает (даже если это не так, вы не можете это исправить), также вам не нужно тестировать Zend_OpenId (он уже описан).Вам нужно протестировать только свой собственный код.Так что было бы неплохо заглушить ответы OpenId.Я не знаю, как выглядит ваш код. Допустим, у вас есть пример из справочника Zend, использующий ваш класс Mygoogle_OpenId_Consumer

if (isset($_POST['openid_action']) &&
    $_POST['openid_action'] == "login" &&
    !empty($_POST['openid_identifier'])) {
    $consumer = new Mygoogle_OpenId_Consumer();
    if (!$consumer->login($_POST['openid_identifier'])) {
        $status = "OpenID login failed.";
    }

} else if (isset($_GET['openid_mode'])) {
    if ($_GET['openid_mode'] == "id_res") {
        $consumer = new Mygoogle_OpenId_Consumer();
        if ($consumer->verify($_GET, $id)) {
            $status = "VALID " . htmlspecialchars($id);
       } else {
           $status = "INVALID " . htmlspecialchars($id);
       }
    } else if ($_GET['openid_mode'] == "cancel") {
        $status = "CANCELLED";
    }
} 

Здесь вы не хотите совершать реальные звонки в Google, а также тестировать Zend_OpenId_Consumerпоэтому нам нужно заглушить Zend_OpenId_Consumer.Чтобы иметь возможность заглушить его в вашем классе, мы бы использовали адаптер, который является либо Zend_OpenId_Consumer, либо вашим фиктивным объектом.

class Mygoogle_OpenId_Consumer extends Zend_OpenId_Consumer
{
    private static $_adapter = null;

    public static function setAdapter($adapter)
    {
        self::$_adapter = $adapter;
    }

    public static function getAdapter()
    {
        if ( empty(self::$_adapter) ) {
            self::$_adapter = new Zend_OpenId_Consumer();
        }

        return self::$_adapter;
    }
.....

И, наконец, в ваших тестах нам нужно создать объект Mock и использовать его для создания заглушки

private function _stubGoogle($successful = false)
    {
        $adapter = $this->getMock('Mygoogle_OpenId_Consumer', array('login','verify'));

        $httpResponse = $successful?:null;
        $adapter->expects( $this->any() )
               ->method('login')
               ->will( $this->returnValue($httpResponse) );

        $adapter->expects( $this->any() )
               ->method('verify')
               ->will( $this->returnValue($successful) );

        Mygoogle_OpenId_Consumer::setAdapter($adapter);
    }

    public function testUserLogsSuccessfullyUsingGoogle()
    {
        $this->_stubGoogle(true);
        //do whatever you need to test your login action:
        //set and send request, dispatch your action
    }

    public function testUserLogsUnSuccessfullyUsingGoogle()
    {
        $this->_stubGoogle(false);
        ...
    }
...