2017-03-02 82 views
0

我有以下數據提供器方法:PHPUnit似乎通過引用而不是通過複製傳遞變量?

public function delta_and_account_provider() 
{ 
    $defaultAccount = json_decode(FileHelper::getJson('account.json')); 
    return [ 
     "acceptable negative adjustment" => 
      [ -20, $defaultAccount], 
     "acceptable positive adjustment" => 
      [ 20, $defaultAccount] 
    ]; 
} 

與測試:

/** 
* @test 
* @dataProvider delta_and_account_provider 
*/ 
public function adjustments_modify_balance_correctly($delta, $account) 
{ 
    $originalBalance = $account->balance; 
    $expectedBalance = $originalBalance + $delta; 

    $actualObject = $this->applyAdjustmentToAccount($delta,$account); 

    $this->assertEquals($expectedBalance, $actualObject->balance); 
} 

defaultAccount具有100的平衡,以及在所述第二數據集中的斷言失敗 - 餘量爲100,而不是

這意味着將變量defaultAccount作爲參考而不是複製到測試的第二次運行(在第二個數據集中)。因爲在第一次運行中,我從100減去20,將defaultAccount保留在80,然後在第二次測試運行期間,它將80加上20,結果保留爲100,而不是120.

測試通過if我更改了數據提供程序爲以下內容:

public function delta_and_account_provider() 
{ 
    $defaultAccount = json_decode(FileHelper::getJson('account.json')); 
    $defaultAccount2 = json_decode(FileHelper::getJson('account.json')); 
    return [ 
     "acceptable negative adjustment" => 
      [ -20, $defaultAccount], 
     "acceptable positive adjustment" => 
      [ 20, $defaultAccount2] 
    ]; 
} 

的例子是有點做作,但我想打,我會期待第二次測試運行使用「乾淨」 $ defaultAccount變量來看,由提供dataprovider而不是之前測試運行的修改過的。

有人可以確認這件事發生在他們身上嗎?或者發生了什麼?

我使用PHP 7.1和5.4的PHPUnit

+0

'$ defaultField'範圍內沒有這樣的變量。 – shudder

+0

json_decode默認會創建一個stdObject。對象默認通過引用傳遞。你有沒有嘗試將json_decode()的第二個參數設置爲true使其成爲一個數組?顯然你必須更新測試,以使用數組符號而不是對象符號 – dbrumann

+0

@ shudder,對不起,我有一個錯字,現在修復 - 謝謝指出! – Pitt

回答

1

默認情況下json_decode()將您的數據建立stdClass的對象。 When you pass this object as a method argument it will be passed by reference,而不是價值。您可以通過json_decode的第二個參數設置爲true繞過這個:

$defaultAccount = json_decode(FileHelper::getJson('account.json'), true); 

,這將產生一個關聯數組,這將通過複製傳遞。

+0

通過閱讀你引用的PHP文檔,它看起來像實際上對象不是通過引用傳遞,而是引用的副本。允許傳遞的參數以與原始引用相同的方式訪問該對象。 – Pitt

+0

我不知道我明白你的意思。通過引用和參考文獻的副本意味着同樣的事情給我,但我不是母語的人。我更新了我的答案以反映文檔中的語言。 – dbrumann

+0

我也沒有;)在PHP文檔中有兩條評論比我能夠更好地解釋這一點。我認爲這個想法是,你有一個引用$ a的引用該對象的引用,並且當你將$ a傳遞給一個方法時,它不會創建該對象的副本,也並不意味着&$ a被傳遞而是將引用so $ a的副本傳遞給該方法。所以像$ b =&$ a – Pitt