溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

使用PHPUnit怎么對私有屬性進行測試

發(fā)布時間:2021-04-08 16:20:40 來源:億速云 閱讀:147 作者:Leah 欄目:開發(fā)技術

這篇文章給大家介紹使用PHPUnit怎么對私有屬性進行測試,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

一、測試類中的私有方法:

class Sample
{
  private $a = 0;
  private function run()
  {
    echo $a;
  }
}

上面只是簡單的寫了一個類包含,一個私有變量和一個私有方法。對于protected和private方法,由于無法像是用public方法一樣直接調用,所以在使用phpunit進行單測的時候,多有不便,特別是當一個類中,對外只提供少量接口,內部使用了大量private方法的情況。

對于protected方法,建議使用繼承的方式進行測試,在此就不再贅述。而對于private方法的測試,建議使用php的反射機制來進行。話不多說,上代碼:

class testSample()
{
    $method = new ReflectionMethod('Sample', 'run');
    $method->setAccessible(true); //將run方法從private變成類似于public的權限
    $method->invoke(new Sample()); //調用run方法
}

如果run方法是靜態(tài)的,如:

private static function run()
{
  echo 'run is a private static function';
}

那么invoke函數(shù)還可以這么寫:

$method->invoke(null); //只有靜態(tài)方法可以不必傳類的實例化

如果run還需要傳參,比如:

private function run($x, $y)
{
  return $x + $y;
}

那么,測試代碼可以改為:

$method->invokeArgs(new Sample(), array(1, 2));
//array中依次寫入要傳的參數(shù)。執(zhí)行結果返回3

【注意】:利用反射的方法測試私有方法雖好,但setAccessible函數(shù)是php5.3.2版本以后才支持的(>=5.3.2)

二、私有屬性的get/set

說完了私有方法,再來看看私有屬性,依舊拿Sample類作為例子,想要獲取或設置Sample類中的私有屬性$a的值可以用如下方法:

public function testPrivateProperty()
{
  $reflectedClass = new ReflectionClass('Sample');
  $reflectedProperty = $reflectedClass->getProperty('a');
  $reflectedProperty->setAccessible(true);
  $reflectedProperty->getValue(); //獲取$a的值
  $reflectedProperty->setValue(123); //給$a賦值:$a = 123;
}

上述方法對靜態(tài)屬性依然有效。

到此,是不是瞬間感覺測試私有方法或屬性變得很容易了。

附:PHPunit 測試私有方法(英文原文)

This article is part of a series on testing untestable code:

  • Testing private methods

  • Testing code that uses singletons

  • Stubbing static methods

  • Stubbing hard-coded dependencies

No, not those privates. If you need help with those, this book might help.

One question I get over and over again when talking about Unit Testing is this:

"How do I test the private attributes and methods of my objects?"

Lets assume we have a class Foo:

<?php
class Foo
{
  private $bar = 'baz';
  public function doSomething()
  {
    return $this->bar = $this->doSomethingPrivate();
  }
  private function doSomethingPrivate()
  {
    return 'blah';
  }
}
?>

Before we explore how protected and private attributes and methods can be tested directly, lets have a look at how they can be tested indirectly.

The following test calls the testDoSomething() method which in turn calls thedoSomethingPrivate() method:

<?php
class FooTest extends PHPUnit_Framework_TestCase
{
  /**
   * @covers Foo::doSomething
   * @covers Foo::doSomethingPrivate
   */
  public function testDoSomething()
  {
    $foo = new Foo;
    $this->assertEquals('blah', $foo->doSomething());
  }
}
?>

The test above assumes that testDoSomething() only works correctly whentestDoSomethingPrivate() works correctly. This means that we have indirectly testedtestDoSomethingPrivate(). The problem with this approach is that when the test fails we do not know directly where the root cause for the failure is. It could be in eithertestDoSomething() or testDoSomethingPrivate(). This makes the test less valuable.

PHPUnit supports reading protected and private attributes through thePHPUnit_Framework_Assert::readAttribute() method. Convenience wrappers such asPHPUnit_Framework_TestCase::assertAttributeEquals() exist to express assertions onprotected and private attributes:

<?php
class FooTest extends PHPUnit_Framework_TestCase
{
  public function testPrivateAttribute()
  {
    $this->assertAttributeEquals(
     'baz', /* expected value */
     'bar', /* attribute name */
     new Foo /* object     */
    );
  }
}
?>

PHP 5.3.2 introduces the ReflectionMethod::setAccessible() method to allow the invocation of protected and private methods through the Reflection API:

<?php
class FooTest extends PHPUnit_Framework_TestCase
{
  /**
   * @covers Foo::doSomethingPrivate
   */
  public function testPrivateMethod()
  {
    $method = new ReflectionMethod(
     'Foo', 'doSomethingPrivate'
    );
    $method->setAccessible(TRUE);
    $this->assertEquals(
     'blah', $method->invoke(new Foo)
    );
  }
}
?>


關于使用PHPUnit怎么對私有屬性進行測試就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI