Boost logo

Boost Users :

From: Ed Johnson (ed_at_[hidden])
Date: 2006-05-03 18:03:30


Paul Giaccone wrote:
> Ed Johnson wrote:
>
>> Paul Giaccone wrote:
>>
>>
>>> Ryo IGARASHI wrote:
>>>
>>>
>>>
>>>> On 3/23/06, Leif Gruenwoldt <leifer_at_[hidden]> wrote:
>>>>
>>>>
>>>>> Is there a way to test the private functions of a class without moving
>>>>> them into public scope during test?
>>>>>
>>>>> What are some strategies for this?
>>>>>
>>>>>
>>>> Try following evil hack.
>>>>
>>>> // someclass_test.hpp
>>>> #define private public
>>>> #define protected public
>>>>
>>>> #include <someclass.hpp>
>>>>
>>>> #undef protected
>>>> #undef private
>>>>
>>>>
>>>>
>>> Evil, evil, evil!
>>>
>>> Slightly less so is what I have done in my code. Define a variable (say,
>>> TESTING) in the makefile or preprocessor definitions of your test
>>> program. In your class definitin, change "private:" to the following:
>>>
>>> #ifdef TESTING
>>> public:
>>> #else
>>> private:
>>> #endif
>>>
>>> Of course, you leave TESTING undefined (or make sure it is undefined) in
>>> your non-test program.
>>>
>>> It's perhaps not nice to look at, but it's less nasty than the above
>>> hack, IMO.
>>>
>>> Paul
>>>
>>>
>> Hi Paul,
>>
>> I wanted to add to your post. I am trying to figure out a good
>> solution to Leif's problem for my own project. Your solution seemed
>> good, but I also want the ability to test just the public interface,
>> without simultaneous access to the private data. When I use the #ifdef
>> TESTING solution, my unit tests never test the classes as they will be
>> used by an end user because all class data is always public. This could
>> lead to a false sense of security from my unit tests.
>>
>>
>
> I'm not sure why you say the class data is public. The #ifdef I was
> proposing is for member functions only, so the class data remains private.

I typically have my private functions and data all under one label of
"private:", so the #idfef TESTING change would affect both for me. I
don't believe your post mentioned that is was only meant for functions?
Either way, all the classes' private functions would always be presented
as public to all the unit tests, which is probably not desirable.

>
> That said, I've now moved to a less hacky approach, which is to define
> member functions used by the test programs only that call the private
> member functions. For example:
>
> private:
> int foo(int a);
>
> #ifdef TESTING
> public:
> int foo_test(int a)
> {
> return foo(a);
> }
> #endif
>
> I'm not sure if this is a preferable alternative to your idea of
> separating members into their own test suites, but it certainly seems
> simpler.
>
> Paul

I like that better than my previous approach, too. It allows finer
grained control than my strategy. However, I think Gennadiy's solution
that he posted in this thread is even less hacky, and gets the job done.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net