ホームページ  >  記事  >  バックエンド開発  >  PHPUnit テストのためのプライベート プロパティとメソッドの機能分析

PHPUnit テストのためのプライベート プロパティとメソッドの機能分析

不言
不言オリジナル
2018-06-12 16:43:421412ブラウズ

この記事では、主にプライベート プロパティとメソッドをテストするための PHPUnit の機能を紹介します。また、PHPUnit を使用してプライベート プロパティとメソッドをテストするための関連する操作スキルと注意事項についても、サンプルの形で詳細に分析します。次のとおりです

この記事の例では、プライベート プロパティとメソッド関数をテストする PHPUnit について説明します。参考のために全員と共有してください。詳細は次のとおりです:

1. テスト クラスのプライベート メソッド:

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

上記は、プライベート変数とプライベート メソッドを含むクラスを単純に記述しています。プロテクトメソッドとプライベートメソッドの場合、パブリックメソッドのように直接呼び出すことができないため、単一のテストにphpunitを使用する場合、特にクラスが外部に少数のインターフェイスしか提供せず、多数のプライベートメソッドを使用する場合は非常に不便です。内部的には。

保護されたメソッドの場合、テストには継承を使用することをお勧めします。そのため、ここでは詳しく説明しません。プライベート メソッドをテストするには、PHP のリフレクション メカニズムを使用することをお勧めします。早速、コードを示します。

class testSample()
{
    $method = new ReflectionMethod('Sample', 'run');
    $method->setAccessible(true); //将run方法从private变成类似于public的权限
    $method->invoke(new Sample()); //调用run方法
}

run メソッドが静的である場合 (例:

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

)

その後、呼び出し関数は次のように書くこともできます:

$method->invoke(null); //只有静态方法可以不必传类的实例化

実行時にパラメーターを渡す必要がある場合は、たとえば:

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

次に、テスト コードを次のように変更できます。

$method->invokeArgs(new Sample(), array(1, 2));
//array中依次写入要传的参数。执行结果返回3

[注]: リフレクションを使用してプライベートをテストする このメソッドは優れていますが、setAccessible 関数は php5.3.2 (>=5.3.2)

2 以降でのみサポートされます。プライベートの取得/設定。属性

プライベート メソッドについて説明した後、プライベート プロパティ $ の値を取得または設定する場合のサンプル クラスを例として見てみましょう。 Sample クラスでは、次のメソッドを使用できます。

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

上記のメソッドは、静的プロパティに対しても有効です。

現時点では、プライベート メソッドやプロパティのテストがすぐに簡単になったようです。

#添付: プライベート メソッドをテストする PHPunit (英語原文)

この記事は、テスト不可能なコードのテストに関するシリーズの一部です:

  • プライベート メソッドのテスト

  • ##シングルトンを使用するコードのテスト
  • スタティック メソッドのスタブ
  • ハードコードされた依存関係のスタブ

  • いいえ、プライベートではありません。これらについてサポートが必要な場合は、この本が役立つかもしれません。

  • 1 つの質問を解決しました。単体テストについて話すときは、次のようになります。

「オブジェクトのプライベート属性とメソッドをテストするにはどうすればよいですか?」

クラスがあると仮定します。 Foo:

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

プロテクト属性とプライベート属性とメソッドを直接テストする方法を検討する前に、それらを間接的にテストする方法を見てみましょう。 .

次のテストは、testDoSomething() メソッドを呼び出し、次に doSomethingPrivate() メソッドを呼び出します。

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

上記のテストは、testDoSomething を前提としています。 () は、testDoSomethingPrivate() が正常に動作する場合にのみ正常に動作します。これは、testDoSomethingPrivate() を間接的にテストしたことを意味します。このアプローチの問題は、テストが失敗した場合、その根本原因がどこにあるのかが直接わからないことです。

#PHPUnit は、PHPUnit_Framework_Assert::readAttribute() メソッドを介した保護属性とプライベート属性の読み取りをサポートしています。PHPUnit_Framework_TestCase::assertAttributeEquals() などの便利なラッパーが存在します。 protected 属性と private 属性に対する明示的なアサーション:

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

PHP 5.3.2 では、ReflectionMethod::setAccessible() メソッドが導入され、リフレクション API:

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

上記のテストでは、testDoSomethingPrivate() を直接テストしていますが、失敗した場合、根本原因をどこで探すべきかがすぐに分かります。

Dave Thomas と Andy Hunt の著書「Pragmatic Unit Testing」の中で次のように書いています。

「一般に、テストのためにカプセル化を破りたくありません。」 (または、母がよく言っていたように、「プライベートを公開しないでください!」)。プライベートまたは保護されたメソッドの背後に隠されている重要な機能がある場合は、ほとんどの場合、クラスをテストできるはずです。 access 、それは、そこから抜け出すのに苦労している別のクラスがあることを示す警告サインである可能性があります。"

つまり、保護されたプライベート属性とメソッドのテストが可能であるというだけでは、意味がありません。これは「良いこと」です。

以上がこの記事の全内容です。その他の関連コンテンツについては、PHP 中国語 Web サイトをご覧ください。

関連提案:

PHP と redis によって実装された悲観的ロック メカニズムの分析

PHP での変数関数の使用の概要

##

以上がPHPUnit テストのためのプライベート プロパティとメソッドの機能分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。