Functional analysis of private properties and methods for PHPUnit testing

Source: Internet
Author: User
This article mainly introduces the PHPUnit test private property and method function, combined with the case form more detailed analysis of the use of PHPUnit for private properties and methods to test the relevant operational skills and considerations, the need for friends can refer to the following

This article describes the PHPUnit test private properties and methods functionality. Share to everyone for your reference, as follows:

First, the private method in the test class:

Class sample{  Private $a = 0;  Private function Run ()  {    echo $a;  }}

The above simply writes a class containing, a private variable and a private method. For protected and private methods, because it cannot be called directly as the public method, it is inconvenient when using PHPUnit for single measurement, especially when a class is provided with only a small number of interfaces, the internal use of a large number of private methods.

For the protected method, it is recommended that you test it in an inherited way, and not repeat it here. For the private method test, it is recommended to use the reflection mechanism of PHP. Words don't say much, on the code:

Class Testsample () {    $method = new Reflectionmethod (' Sample ', ' Run ');    $method->setaccessible (TRUE); Change the Run method from private to public-like permission    $method->invoke (New Sample ());//Call the Run method}

If the Run method is static, such as:

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

Then the Invoke function can also be written like this:

$method->invoke (NULL); Only static methods can be instantiated without passing classes

If run also needs to pass parameters, such as:

Private function Run ($x, $y) {  return $x + $y;}

Then the test code can be changed to:

$method->invokeargs (New Sample (), Array (1, 2)), and in//array, writes the parameter to be passed in turn. Execution results returned 3

"Note": It is good to test the private method with reflection, but the setaccessible function is only supported after the php5.3.2 version (>=5.3.2)

Second, the get/set of the private property

After the private method is finished, take a look at the private property, still taking the sample class as an example, to get or set the value of the private property $ A in the sample class can be as follows:

Public Function Testprivateproperty () {  $reflectedClass = new Reflectionclass (' Sample ');  $reflectedProperty = $reflectedClass->getproperty (' a ');  $reflectedProperty->setaccessible (true);  $reflectedProperty->getvalue (); Gets the value of  $ A $reflectedProperty->setvalue (123);//assigns a value to $ A: $a = 123;}

The above method is still valid for static properties.

To this, it is not instantaneous to feel that testing a private method or property becomes easy.

Attached: PHPunit test Private Method (original English)

This article was part of the 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, the this book might help.

One question I get over and over again when talking about Unit testing are this:

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

Lets assume we have a class Foo:

<?phpclass 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 has a look in how they CA n be tested indirectly.

The following test calls the Testdosomething () method which in turn calls Thedosomethingprivate () method:

<?phpclass Footest extends phpunit_framework_testcase{  /**   * @covers foo::d osomething   * @covers foo:: Dosomethingprivate   *  /Public Function testdosomething ()  {    $foo = new Foo;    $this->assertequals (' blah ', $foo->dosomething ());}  }? >

The test above assumes that testdosomething () is only works correctly whentestdosomethingprivate () works correctly. This means, we have indirectly testedtestdosomethingprivate (). The problem with this approach is if the test fails we do not know directly where the root cause for the failure are . It could is 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:

<?phpclass 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:

<?phpclass Footest extends phpunit_framework_testcase{  /**   * @covers Foo::d osomethingprivate */   Public  function Testprivatemethod ()  {    $method = new Reflectionmethod (     ' Foo ', ' dosomethingprivate '    );    $method->setaccessible (TRUE);    $this->assertequals (     ' blah ', $method->invoke (new Foo)    );}  }? >

In the test above we directly test testdosomethingprivate (). When it fails we immediately know where to look for the root cause.

I agree with Dave Thomas and Andy Hunt, who write in their book "Pragmatic Unit Testing":

"In general, you don't want to break any encapsulation for the sake of testing (or as Mom used to say," don ' t expose your Privates! "). Most of the time, you should is able to test a class by exercising it public methods. If There is significant functionality that's hidden behind private or protected access, that's might be a warning There ' s another class in there struggling-get out. "

So:just because the testing of protected and private attributes and methods is possible does isn't mean that this is a "goo D thing ".

The above is the whole content of this article, I hope that everyone's learning has helped, more relevant content please pay attention to topic.alibabacloud.com!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.