2017-06-18 31 views
0

使用ci-php-unit-test庫爲PHP/codeigniter和單元測試控制器方法執行單元測試。在PHP/Codeigniter中嘲笑外部庫

在解決如何模擬使用composer安裝的外部庫時遇到問題。

我的SUT的方法是:

function twitter() 
{ 
    $this->load->model('misc/twitter_model'); 
    $request_token = []; 

    $request_token['oauth_token'] = $_SESSION['twitter_oauth_token']; 
    $request_token['oauth_token_secret'] = $_SESSION['twitter_oauth_token_secret']; 
    if ((isset($_GET['oauth_token']) 
     && ($request_token['oauth_token'] !== $_GET['oauth_token']))) 
    { 
     log_message('info','abort something is wrong!'); 
    } 
    else 
    { 
     $connection = new Abraham\TwitterOAuth\TwitterOAuth(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET, $request_token['oauth_token'], $request_token['oauth_token_secret']); 
     $access_token = $connection->oauth("oauth/access_token", array("oauth_verifier" => $_REQUEST['oauth_verifier'])); 
     $this->session->set_userdata('twitter_access_token',$access_token); 
     redirect(get_session('twitter_callback1')); 
    } 
} 

我的測試方法(到目前爲止)是:

public function test_twitter() 
{ 
    $_SESSION['twitter_oauth_token'] = 'twitter_oauth_token'; 
    $_SESSION['twitter_oauth_token_secret'] = 'twitter_oauth_token_secret'; 

    $this->request->setCallable(
     function (& $CI) { 
      // Get mock object 
      $twitter_oa = $this->getMockBuilder('TwitterOAuth') 
       ->disableOriginalConstructor() 
       ->setMethods(['oauth']) 
       ->getMock(); 
      $twitter_oa->method('oauth') 
       ->willReturn('access_token'); 
     } 
    ); 
    $output = $this->request('GET','callbacks/twitter',['oauth_token'=>'twitter_oauth_token']); 
    var_export($output); 
} 

但因爲它沒有被嘲笑被執行原來的數據庫 - $twitter_oa ISN沒有附加到CI實例。

這是因爲外部庫在codeigniter控制器被實例化後沒有被實例化。 (這是setCallable方法)

我的問題是,如何在codeigniter控制器實例化之後模擬TwitterOAuth,以便它可以返回設置測試文本? (顯然不是實例化Twitter的Oauth庫)

回答

0

好的,所以當你看到一個新的Class();在單元測試中,你必須重新工作。這可能不是最好的選擇,但這適用於我。

在SUT

,控制器代碼現在:

function twitter() 
{ 
    $this->load->model('misc/twitter_model'); 
    $request_token = []; 

    $request_token['oauth_token'] = $_SESSION['twitter_oauth_token']; 
    $request_token['oauth_token_secret'] = $_SESSION['twitter_oauth_token_secret']; 
    if ((isset($_GET['oauth_token']) 
     && ($request_token['oauth_token'] !== $_GET['oauth_token']))) 
    { 
     log_message('info','abort something is wrong!'); 
    } 
    else 
    { 
     $connection = $this->twitter_connection($request_token['oauth_token'],$request_token['oauth_token_secret']); 
     $access_token = $connection->oauth("oauth/access_token", array("oauth_verifier" => $_REQUEST['oauth_verifier'])); 
     $this->session->set_userdata('twitter_access_token',$access_token); 
     redirect(get_session('twitter_callback1')); 
    } 
} 

/** 
* @param $token 
* @param $secret 
* @return \Abraham\TwitterOAuth\TwitterOAuth 
* 
* @codeCoverageIgnore 
* 
*/ 
public function twitter_connection($token, $secret) 
{ 
    return new Abraham\TwitterOAuth\TwitterOAuth(
     TWITTER_CONSUMER_KEY, 
     TWITTER_CONSUMER_SECRET, 
     $token, 
     $secret); 
} 

有一個在APPPATH.tests /嘲笑/ external_libaries一個新的文件用:

class MockTwitterOAuth 
{ 
    public function oauth() 
    { 
     return 'access_token'; 
    } 
} 

和測試代碼現在是:

public function test_twitter() 
{ 
    $_SESSION['twitter_oauth_token'] = 'twitter_oauth_token'; 
    $_SESSION['twitter_oauth_token_secret'] = 'twitter_oauth_token_secret'; 
    $_SESSION['twitter_callback1'] = 'cb1'; 
    require_once(APPPATH.'tests/mocks/external_libraries/MockTwitterOauth.php'); 
    $twitter_connection = new MockTwitterOAuth(); 
    MonkeyPatch::patchMethod('Callbacks',[ 
     'twitter_connection'=>$twitter_connection 
    ]); 
    $output = $this->request('GET','callbacks/twitter',['oauth_token'=>'twitter_oauth_token']); 
    $this->assertNull($output); 
    $this->assertResponseCode(HTTP_FOUND); 
    $this->assertRedirect(base_url('cb1')); 
    $this->assertEquals('access_token',$_SESSION['twitter_access_token']); 
} 

訣竅是讓twitter連接正常返回一個新的TwitterOAuth類,但是當系統是單元測試,而是返回只有一種方法的MockTwitterOAuth類。這可以通過monkeypatching控制器代碼來完成。

希望這個回答對其他人很有用,如果你還沒有使用它,https://github.com/kenjis/ci-phpunit-test是相當不錯的,即使它很難開始。推薦購買伴侶書!