Hi Dieter,

> I almost reduce the use of super global variables inside functions of
> PMA_DisplayResults class.
> Most of the fields are set while executing the getTable() function since
> they cannot set while executing the constructor.
>
> Now I'm move into writing tests.
> I am facing to a problem with writing tests.
> How can I access or set the private variables, by a test ?
> The already existed tests also failing due to this change.
> Your suggestions will very helpful.



I didn't have a look at the current tests and at PMA_DisplayResults
class, so I won't be able to go into specifics about your tests, but I
will try to answer your questions, and point you in a direction.

Accessing or setting private variables in a class/method is not
possible during a unit test.
The idea of unit tests is to test the functionality of a class method
or global function by testing the output of it, or catching errors.
You expect a certain behaviour of the method/function depending on the
value of the input parameters (or environmental states, like global
variables, database content, or config settings).
So basically you think of all different situations that can affect the
behaviour of the method/function, define what kind of result this
would give and write a test that sets up the situation and test
(assert) the output of the function/method.

When writing unit tests, you should keep in mind that you are only
testing the behaviour of that function/method. Any functions/methods
used by a function/method should be tested seperately. By which I mean
that you must assume when testing a function/method that the
functions/methods that are used in that method, work correctly.
To make things easier for you, you can define stubs/mocks [0] that
replace the methods/functions used in a function/method you are
testing. This way you don't have to set up a complete environment, but
can concentrate on what the function/method does.

As an example

If you have a class that gets values from a database :

class DbValues
{
   private $_values;

   __construct()
   {
       $this->_values = array();
   }

   public function getValuesFromDb()
   {
       // functionality making a connection to a database, executing a
query and setting the resulting values to $_values.
   }

   public function getValues()
   {
       return $this->_values;
   }

  public function count()
  {
     return count($this->getValues());
  }
}


And you want to test the behaviour of the count() method. The only way
to populate the _values variable in this example would be by setting
up a database with different sets of values, for each case you want to
test and call the getValuesFromDb() method, OR, you can  define a stub
that replaces the getValues() method and let it return an array with
the necessary amount of values (depending on what you want to test).
This way you avoid having to set up a complicated testing environment,
when testing a single class method. (Note : when testing the
getValuesFromDb() method you will probably have to set up a database,
but that's because that method is all about connecting to a database
and getting data from it, but all other methods in this class can
assume that the getValuesFromDb works, so there is no need to
replicate the complicated test environment every time)

I suggest you read up a bit on testing class methods and the use of
stubs/mocks. I hope my example didn't confuse you too much.

[0] http://www.phpunit.de/manual/current/en/test-doubles.html#test-doubles.stubs


Thank you very much for spending your time for clarify this with valuable and enough information.
I completely agree with you, on writing unit tests independent/separate from another layer/function.
Mock objects/stubs are helpful in that case.

At the moment there are around 25 private fields in PMA_DisplayResults class.
What I am thinking of implement getter setter methods for all those and use getters and setters where needed.
In that way I will be able to set those private fields even from the tests.
What do you think on this ?


Regards !


Hi Chanaka,

When writing test cases we might have to test protected/private functions as well. The method used in PMA is by using php Refection class. They used setAccessible method to make them public for test class. There is a method in reflection class called getProperties which can used for access protected and private attributes. Refer this [1] for more details. But I am not sure is it a good approach when testing. 

[1] - http://php.net/manual/en/reflectionproperty.setaccessible.php 


Hi Yasitha,

Thanks for your information.
I have already referred some tests done by you, accessing to private functions.
I'll use the same way for testing private methods.

Regards !
--
____________________________________

Chanaka Indrajith
Bsc.Computer Engineering Undergraduate
Faculty of Engineering
University of Peradeniya
Sri Lanka
____________________________________