PHP Unit testing tool PHPUNIT deep usage (III) _ php skills

Source: Internet
Author: User
In the first two articles in this series, PHP Unit Testing Tool: PHPUNIT preliminary study and PHP Unit Testing Tool: PHPUNIT in-depth usage (2, this section describes the basic usage of phpunit and some important usage of phpunit. In the first two articles in this series, PHP Unit Testing Tool: PHPUNIT preliminary study and PHP Unit Testing Tool: PHPUNIT in-depth usage (2, this section describes the basic usage of phpunit and some important usage of phpunit.

In this article, I will introduce you to the two advanced concepts and usage in phpunit, although it is not necessarily used in your daily unit testing, however, understanding and learning their usage is very important for learning phpunit.

  Annotations in Phpunit

Developers with experience in other programming languages should be familiar with Annotations (Annotations). In fact, in phpunit, a simple comment below can also be considered as Annotations:

 assertTrue($love);}}?>


As you can see, a piece of text marked with/***/can be considered as an Annotations. However, Annotations are not just simple Annotations, it is the annotation of information or metadata associated with a program element. it does not affect the running of the program, but the related software tools or frameworks can convert it into special metadata tags, to help developers improve efficiency with less code (for example, through. If you are familiar with Java, you will find that Annotations are widely used in Java SE 5 and frameworks such as Spring.

However, because php is not a compilation language like Java, it lacks the Annotations parsing mechanism. Fortunately, phpunit provides such a function. the following code is used as an example:

 


The above is just a simple addition example. For this reason, we use Annotations to write a unit test. in the last two articles, we used the method of manually writing unit tests, this article describes how to use the phpunit command line to automatically generate a unit test framework. the method is as follows:

First, save the above class as MyMathClass. php, and then run the following command on the command line:

phpunit –skeleton-test MyMathClass

Phpunit automatically generates the following framework unit test code:

 object = new MyMathClass;}/*** Tears down the fixture, for example, closes a network connection.* This method is called after a test is executed.*/protected function tearDown(){}/*** @todo Implement testAddValues().*/public function testAddValues(){// Remove the following lines when you implement this test.$this->markTestIncomplete('This test has not been implemented yet.');}}?>

As you can see, phpunit automatically introduces the original MyMathClass for the unit test code we generated. php also generates setUp and tearDown methods, but the only core unit test code is left for us to write. If we want to generate the unit test code more quickly on this basis, how can we implement it? That's right. it's just using annotations! We can add the following annotations to the original MyMathClass. php.

 

Then run the following command in the command line as above:

  phpunit –skeleton-test MyMathClass

At this time, the following unit test code will be generated for us:

 assertEquals(3,$this->object->addValues(1,2));}?>

Have you seen it? If the annotation @ assert () = 3 is added to the original class, phpunit automatically generates the correct unit test code for us. Of course, you can refer to the phpunit manual to learn more about the rules for using the @ assert annotation.

The following is an example of annotations. Assume that a method in our program only requires data input and does not rely on XML or the database to provide data sources. in order to test this method, one method we may think of is to set a test dataset in the program for testing, but here we will introduce a simple method, that is, to use annotation @ dataProvider to modify MyMathClass. php is as follows:

 assertEquals($sum,$this->object->addValues($a,$b));}?>

The annotation @ dataProvider is used to indicate that the data provider of the test case is an array returned by the provider method. Therefore, in unit test, the first element in the array is assigned to $ a, the second element is assigned to B, and the second element is assigned to sum. you can see that, the data provided by the above 3rd arrays cannot pass the unit test, because 1 + 5 is not equal to 7.

In addition, two commonly used annotations are briefly introduced. for example, the @ expectedException annotation can be used to test whether an exception is thrown correctly in the code, for example:

 

The annotation method is used to indicate that the exception type that must be thrown in testException is InvalidArgumentException.

The other is the @ cover annotation. The function of phpunit is to identify only the methods or scopes in the class to generate test code, for example:

/**     * @covers SampleClass::publicMethod     * @covers SampleClass::
      * @covers HelperClass
 
       */    public function testMethod()    {        $result = SampleClass::method();}
 

Phpunit only generates unit test code for the publicMethod method in the SampleClass class, all non-public declared methods in the SampleClass class, and the HelperClass class or one of its parent classes.

Mocking in Phpunit

Before introducing Mocking, let's take a look at why Mocking is used. For example, if you want to test a database application in an application, however, if the testing of this database requires a lot of resources and code for compiling complicated unit tests, you can try Mocking technology. Example:


 

In the above example, we simulate a database operation and think it takes a long time to run. The unit test code is as follows:

 db = new Database();}public function tearDown(){unset($this->db);}/*** Test that the "really long query" always returns values*/public function testReallyLongReturn(){$mock = $this->getMock('Database');$result = array(array(1,'foo','bar test'));$mock->expects($this->any())->method('reallyLongTime')->will($this->returnValue($result));$return = $mock->reallyLongTime();$this->assertGreaterThan(0,count($return));}}?>

Pay attention to the interesting part of this code. here, the getMock object method in phpunit is used. here, it is actually simulating the generation of a "pseudo instance" of the Database class, $ mock is generated here as a mock object instance for subsequent unit tests. The following three lines of code

$mock->expects($this->any())->method('reallyLongTime')->will($this->returnValue($result));

Their meaning is: no matter how long the method reallyLongtime is executed, the result of the $ result array is always returned. In this way, you can easily use mocking technology to bypass some complex logic parts in unit testing, saving a lot of valuable time to improve testing efficiency.

The following example illustrates the more advanced Mockbuilder usage in Mocking technology. The above examples are still described as follows:

 getMockBuilder('Database')->setMethods(array('reallyLongTime'))->disableAutoload()->disableOriginalConstructor()->getMock();$result = array(array(1,'foo','bar test'));$stub->expects($this->any())->method('reallyLongTime')->will($this->returnValue($result));$this->assertGreaterThan(0,count($return));}?>

By using Mockbuilder, we can initialize a mock object without using the constructor method. This code is actually the same as a code snippet, but pay attention to the two new methods: disableAutoload and disableOriginalConstructor, the built-in autoload initial constructor of php and the original constructor of this class are prohibited. Let's look at another example:

 getMock('Database',array('reallyLongTime'));$stub->expects($this->any())->method('reallyLongTime')->with($this->isType('array'));$arr = array('test');$this->assertTrue($stub-> reallyLongTime ($arr));}?>

The above is the PHP Unit testing tool PHPUNIT in-depth usage (3) _ php skills content, more relevant content please follow the PHP Chinese network (www.php1.cn )!

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.