2014
Jun
23

Write a php unit test is not a hard work. I think you had already use phpunit before read this article. But sometimes, the expert engineer create a private method to prevent other engineers to call.

Sorry! I am not a expert engineer and seldom use private method.

Private method is a big problem for phpunit test. The phpunit could not call a private method so it will be failed to be tested.

I will show you how to test a private method later.

A normal unit test

Let's start a normal php code to be tested. The following is a php code name food.php and has a class call food, also has a private function getName

Example
  1. <?php
  2.  
  3. class food {
  4. private function getName()
  5. {
  6. return "chicken";
  7. }
  8. }

How do you test a php method?

If you don't know getName is a private method, maybe you will use the following sample code to test food class.

Example
  1. <?php
  2. require_once "food.php";
  3.  
  4. class FoodTest extends PHPUnit_Framework_TestCase
  5. {
  6.  
  7. public function testGetName()
  8. {
  9. $obj = new food();
  10.  
  11. $name = $obj->getName();
  12.  
  13. $this->assertEquals('chicken', $name);
  14. }
  15.  
  16. }

This a most simple unit test in php. But it is not the key point today.

When you run this unit test, you will get the fatal error below.

PHP Fatal error: Call to private method food::getName() from context 'FoodTest'

Using ReflectionClass to test.

If you need to test a private method. You should study ReflectionClass from here.

The first step is to new constructor ReflectionClass then we will get the method by getMethod method of ReflectionClass.

Then we should call setAccessible to set it to be true. Finally execute this method that we got from ReflectionClass.

phpunit test source code
  1. <?php
  2. require_once "food.php";
  3.  
  4. class FoodTest extends PHPUnit_Framework_TestCase
  5. {
  6.  
  7. public function testGetName()
  8. {
  9. $obj = new food();
  10.  
  11. $ref = new ReflectionClass('food');
  12. $method = $ref->getMethod('getName');
  13. $method->setAccessible(true);
  14. $name = $method->invokeArgs($obj, array());
  15.  
  16. $this->assertEquals('chicken', $name);
  17. }
  18.  
  19. }

Read the executing result of phpunit.

Result
  1. phpunit test.php
  2.  
  3. PHPUnit 4.1.2 by Sebastian Bergmann.
  4.  
  5. .
  6.  
  7. Time: 64 ms, Memory: 2.00Mb
  8.  
  9. OK (1 test, 1 assertion)
.... You pass the test.

回應 (Leave a comment)