2017-03-02 43 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