[Phpmyadmin-devel] Refactoring: Displaying query results
Chanaka Dharmarathna
pe.chanaka.ck at gmail.com
Sat Jul 7 19:15:54 CEST 2012
> 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
____________________________________
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.phpmyadmin.net/pipermail/developers/attachments/20120707/9c929c89/attachment.html>
More information about the Developers
mailing list