PHPUnit似乎通过引用而不是通过副本传递变量?

时间:2017-03-02 19:24:56

标签: php phpunit

我有以下dataprovider方法:

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而不是120.

这意味着变量defaultAccount作为参考而不是通过复制传递给第二次测试(在第二个数据集中)。因为在第一次运行中,我从100减去20,将defaultAccount保留为80,然后在第二次测试运行期间,它将80添加到80,最终结果为100,而不是120.

如果我将dataprovider更改为以下内容,则测试通过:

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

这个例子有点做作,但我想指出我希望第二次测试运行使用数据提供者提供的'clean'$ defaultAccount变量,而不是之前测试运行中的修改过的变量。

有人可以确认这也发生了吗?或者是怎么回事?

我使用PHP 7.1和phpunit 5.4

1 个答案:

答案 0 :(得分: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);

这将生成一个关联数组,它将通过副本传递。