PHP 访问私有和受保护的成员变量

示例

反射通常用作软件测试的一部分,例如在运行时创建/实例化模拟对象。这对于在任何给定时间点检查对象的状态也非常有用。这是在单元测试中使用Reflection来验证受保护的类成员是否包含期望值的示例。

下面是一个非常基础的汽车课。它具有受保护的成员变量,该变量将包含代表汽车颜色的值。由于成员变量受保护,因此我们无法直接访问它,而必须使用getter和setter方法分别检索和设置其值。

class Car

{

    protected $color

    

    public function setColor($color)

    {

        $this->color = $color;

    }

    

    public function getColor($color)

    {

        return $this->color;

    }

}

为了测试这一点,许多开发人员将创建一个Car对象,使用设置汽车的颜色,使用检索颜色,并将该值与他们设置的颜色进行比较:Car::setColor()Car::getColor()

/**

 * @test

 * @covers     \Car::setColor

 */

public function testSetColor()

{

    $color = 'Red';

    $car = new \Car();

    $car->setColor($color);

    $getColor = $car->getColor();

        

    $this->assertEquals($color, $reflectionColor);

}

从表面上看,这似乎还可以。毕竟,所有要做的就是返回protected成员变量的值。但是此测试在两个方面存在缺陷:Car::getColor()Car::$color

  1. 它执行的测试不在此测试范围内Car::getColor()

  2. 这取决于哪个错误本身可能使测试具有错误的肯定或否定。Car::getColor()

让我们看看为什么不应该在单元测试中使用,而应该使用Reflection。假设开发人员被分配了一项任务,以向每种汽车颜色添加“金属”。因此,他们尝试修改,以在汽车的颜色前添加“金属”:Car::getColor()Car::getColor()

class Car

{

    protected $color

    

    public function setColor($color)

    {

        $this->color = $color;

    }

    

    public function getColor($color)

    {

        return "Metallic "; $this->color;

    }

}

看到错误了吗?开发人员使用分号代替串联运算符,以使“ Metallic”成为汽车的颜色。结果,无论汽车的实际颜色是什么,只要被调用,都会返回“ Metallic”。结果,即使工作得很好并且不受此更改的影响,我们的单元测试也将失败。Car::getColor()Car::setColor()Car::setColor()

那么,如何验证Car::$color包含通过设置的值?我们可以使用Refelection直接检查受保护的成员变量。那么我们怎么做呢?我们可以使用Refelection使受保护的成员变量可被我们的代码访问,以便它可以检索值。Car::setColor()

让我们先看一下代码,然后将其分解:

/**

 * @test

 * @covers     \Car::setColor

 */

public function testSetColor()

{

    $color = 'Red';

    $car = new \Car();

    $car->setColor($color);

    

    $reflectionOfCar = new \ReflectionObject($car);

    $protectedColor = $reflectionOfForm->getProperty('color');

    $protectedColor->setAccessible(true);

    $reflectionColor = $protectedColor->getValue($car);

    

    $this->assertEquals($color, $reflectionColor);

}

这是我们使用Reflection获取Car::$color上面代码中的value的方式:

  1. 我们创建一个新的ReflectionObject代表我们的Car对象

  2. 我们得到一个ReflectionProperty用于Car::$color(此“代表”Car::$color变量)

  3. 我们使Car::$color无障碍

  4. 我们得到的价值 Car::$color

如您所见,通过使用Reflection,我们可以得到的价值,Car::$color而不必调用可能导致无效测试结果的任何访问器函数。现在,我们的单元测试安全且准确。Car::getColor()Car::setColor()

以上是 PHP 访问私有和受保护的成员变量 的全部内容, 来源链接: utcz.com/z/337883.html

回到顶部