我编写了一个简单的单元测试,它测试一个被测试类的方法返回一个自身的实例,传递的参数不受影响。
即。由于方法返回$this->theClass->theMethod($param1, $param2);
,$param1
不应修改$param2
或$this
。但是,我在运行该方法后立即var_dump($param1)
看到$ param1已被修改。
提供更多背景信息:
鉴于有User
名为 Bob Jones 。
$user = factory(App\User::class, 'withCompany')
->make([
'name' => 'Bob',
'surname' => 'Jones',
'member_id' => 1
]);
并且 Bob 有一些元UserData
,其中还有属性name
和surname
(值相等)。
$userData = factory(App\UserData::class)
->make($this->mapUserToUserData($user) + ['member_id' => 1]);
当我将name
元数据对象中的UserData
属性更改为' Fred '
$userData->m_field_id_4 = 'Fred';
我同步对象之间的数据(即我称之为测试方法)
$this->syncUserData->sync($user, $userData);
然后,User
对象仍应保留名称' Bob '
$originalUser = $this->syncUserData->getOriginalUser();
$syncedUser = $this->syncUserData->getSyncedUser();
$this->assertEquals('Bob', $originalUser->name);
$this->assertEquals('Fred', $syncedUser->name);
如上面的注释所述,$user
对象已被更改,没有任何直接修改。
为完整起见,完整代码如下:
SyncUserDataTest.php
class SyncUserDataTest extends TestCase
{
use UserDataMapper;
protected $syncUserData;
public function setUp()
{
parent::setUp();
$this->syncUserData = new App\Helpers\SyncUserData();
}
public function test_it_returns_the_unmodified_user()
{
$user = factory(App\User::class, 'withCompany')
->make([
'name' => 'Bob',
'member_id' => 1
]);
$userData = factory(App\UserData::class)
// And the data is the same
->make($this->mapUserToUserData($user) + ['member_id' => 1]);
$userData->m_field_id_4 = 'Fred';
$this->syncUserData->sync($user, $userData);
$originalUser = $this->syncUserData->getOriginalUser();
$syncedUser = $this->syncUserData->getSyncedUser();
$this->assertEquals('Bob', $originalUser->name);
$this->assertEquals('Fred', $syncedUser->name);
}
}
SyncUserData.php
<?php
namespace App\Helpers;
class SyncUserData
{
/**
* Has any data changed.
*
* @var bool
*/
private $hasChanged = false;
/**
* The original User object without modifications.
*
* @var \App\User
*/
private $originalUser;
/**
* The updated User object that has had data synced from the UserData object.
*
* @var \App\User
*/
private $syncedUser;
/**
* Sync data from UserData with a User object.
*
* @param \App\User $user
* @param \App\UserData $against
* @return $this
*/
public function sync($user, $against)
{
$this->setOriginalUser($user);
$updatedUser = $this->applyChangesToUser($user, $against);
$this->setSyncedUser($updatedUser);
return $this;
}
/**
* Check if two values are the same.
*
* @param string $check
* @param string $against
* @return bool
*/
public function hasChanged($check, $against)
{
if ($check != $against) {
$this->hasChanged = true;
return true;
}
return false;
}
/**
* @param \App\User $user
* @return $this
*/
public function setSyncedUser($user)
{
$this->syncedUser = $user;
return $this;
}
/**
* @param \App\User $user
* @return $this
*/
public function setOriginalUser($user)
{
$this->originalUser = $user;
return $this;
}
/**
* Get the updated User object with data synced from the UserData object.
*
* @access public
* @return mixed
*/
public function getSyncedUser()
{
return $this->syncedUser;
}
/**
* Get the original User object.
*
* @access public
* @return mixed
*/
public function getOriginalUser()
{
return $this->originalUser;
}
/**
* Was any data different between the User and UserData objects.
*
* @access public
* @return bool
*/
public function wasDataChanged()
{
return $this->hasChanged;
}
/**
* @param $user
* @param $against
*/
private function applyChangesToUser($user, $against)
{
if ($this->hasChanged($user->name, $against->m_field_id_4)) {
$user->name = $against->m_field_id_4;
}
if ($this->hasChanged($user->surname, $against->m_field_id_5)) {
$user->surname = $against->m_field_id_5;
}
return $user;
}
}
很简单,我的问题是 - $user
对象的name
属性如何更改?
答案 0 :(得分:0)
您似乎遇到的问题是默认情况下对象是通过引用传递的,因此当您更新对象时,会更新所有对象。
这方面的方法包括(但可能不限于):