首页 > 解决方案 > 测试设置私有属性:我们可以使用模拟设置值并反映属性来检查是否设置了值吗?

问题描述

我有“这样做的方式”和“如何完成”的问题。

Class realClass {

     private $privateProperty;

     public function __construct($someArray, $someString) {
          // stuff
     }

     public function setProperty($someArray) {
          $this->privateProperty = $someArray;
     }
}


class testRealClass extends TestCase {

    // creating a mock because don't want to have tests depending on arguments passed to the constructor
    public function setUp(): void
    {
         $this->classToTest = $this->getMockBuilder(realClass::class)
             ->disableOriginalConstructor()
             ->setMethods(null)
             ->getMock();
    }

    // testing the set of the variable. In order to know if it was set, without using a getter,
    // we probably need to use reflection
    public function testSetPrivateProperty() {
         $this->classToTest->setProperty([1,2,3]);

         // This will not work as the property is private
         // echo $this->classToTest->privateProperty;

         // Reflecting the mock, makes sense? How does this work?
         $reflect = new \ReflectionClass($this->classToTest);
         $property = $reflect->getProperty('privateProperty');
         $property->setAccessible(true);
         var_dump($property->getValue($this->classToTest));
    }
}

执行此操作时,我得到一个 ReflectionException: Property privateProperty 不存在。

如果我对反射进行 print_r->getProperties,我可以在那里看到该属性。

我知道这很容易通过 realClass 中的吸气剂来实现,但将此作为练习。

这是否有意义,或者这将不起作用,因为它只是错误的?

谢谢大家

(在这里写了代码,所以如果我缺少“;”、“(”等,请忽略它:)

标签: phpunit-testing

解决方案


使用反射 API 进行测试很少是一个好主意。然而,真正的问题是 - 如果没有人可以访问它,为什么还要拥有私有财产?显然,该属性用于该类的另一个方法中。$this->property所以,这里的干净解决方案是删除所有反射代码,然后在类本身中创建一个 getter,并替换所有对 的调用$this->getProperty(),然后您可以轻松地测试它。

对于这个问题的更普遍的看法,私有属性和方法并不意味着要测试,它们是私有的,因为它们对所有人隐藏了它们的数据,包括测试器类。您的类拥有的私有字段和属性越多,它的可测试性就越少,因此当这成为障碍时,最好将类分成两个,将其中一个私有方法公开。


推荐阅读