Re: Friend class

332 views
Skip to first unread message

Martin Ertsås

unread,
Jan 28, 2014, 3:41:17 AM1/28/14
to cppu...@googlegroups.com
One of the reasons this isn't working is that TEST_GROUP(TestCode) does magic, and creates a class with another name than TestCode. You will need to have a look at the macros to see what it is really named, but I'm not sure if it will always be named that or if that is subject to change (Bas?).

When it comes to testing private functions, I'm in general sceptical. What you want to test is that the class behaves as it should, so you test Func1, which would use Func2 (if not, there are no need to have Func2). You are not really interested in the low level detail of what Func2 really does, but you are interested in that calling Func1 has the desired result. If that means calling Func2, so be it, but my test don't care, you are basically testing Func2 through Func1.

Adding tests on private functions are possible, but will generally make you code harder to change, as you are "locking in" the implemntation details of your class, and not your interface. The only reason I have seen for doing it is to get legacy code under test (Legacy code = code without test, definition stolen from James Grenning).

If you really want to test private functions (done myself on legacy code) you can do the following:

#define private public
#include "headerfile_of_class_you_want_to_test"

but as I said, if this is to get legacy code under test, you should do some work and refactor the need for this away.

- Martin

On 01/28/14 09:00, shiva prasad wrote:
Hi all,

I started writing CppUTest for a X class. I want to test the private member functions of the class.. How do i make my test code to be friend of X class.
I tried the below code but it is not working, Can anyone please let me know how to access the private functions..

Class X
{
friend class TestCode;

public:
void Func1();

private:
void Func2();
}


Unit test code :

TEST_GROUP(TestCode)
{
X xobj;
TEST_SETUP()
{
// Initialize stuff
}
 
TEST_TEARDOWN()
{
// Clear stuff
}
};
TEST(TestCode,TestCase_Name)
{
xobj.Func2();  --> this throws an error of inaccessible function. 

}



Thank you for the help.

Regards
Shiva
--
You received this message because you are subscribed to the Google Groups "cpputest" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cpputest+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Bas Vodde

unread,
Jan 29, 2014, 12:38:12 AM1/29/14
to cppu...@googlegroups.com

Hi Martin,

Not planning to change the name, but you never know :P

Bas

Bas Vodde

unread,
Jan 29, 2014, 12:39:39 AM1/29/14
to cppu...@googlegroups.com

Hi Shiva,

As Martin already mentioned, you probably do not want to use friend. In fact, in C++, when you need to use friend there is probably something wrong. I wish the keyword didn’t existed (like many other keywords in C++).

If you want to test private functions, it is recommended to do that via the public interface. If you can’t, then you can delete the private method without any harm. If the private method is too big, then probably your class is too big and you might want to extract a class.

Hope this helps!

Bas

Andy Neebel

unread,
Feb 8, 2014, 11:54:52 AM2/8/14
to cppu...@googlegroups.com
One case I came across recently was when I wanted to test a class that derived from a higher level class.  All I really wanted to test were the protected functions that a child class provides for the base class.  I technically could have tested them through the base class, but the only public function is a state machine that would require a fair amount of extra test code to cycle through in order to test the class.  All I needed to test in the child classes was the protected virtual functions, so friend was an easy way to get access to those functions without a bunch of other work.  The base class was a generic state machine for control and diagnostics of a FET, and the child classes were the specific implementations of how to command and read feedback from each type of FET that we use.
 
I do agree, friend to access private members isn't generally a good design, but there's no other way I could come up with to make a base class/child class interface accessible without completely exposing the interface to all classes, and in this case I really didn't want to do that.  Maybe there would have been a better way to design it, but that seemed like the good design to me.  Despite using friend, I think I was using it in an ok fashion in this case, since it was only to test a defined interface between two classes without completely exposing that interface.  If I had been in C# I probably would have used internal and InternalsVisibleTo, but C++ doesn't have anything beside friend.
 
Andy

Bas Vodde

unread,
Feb 9, 2014, 4:22:32 AM2/9/14
to cppu...@googlegroups.com

Hi Andy,

Well, I can’t imagine any good usage of the friend keyword. When you need to test private methods, then usually your class is too big and it is best to extract soem of the logic to another class and use that one.

But to make it more constructive. You can test protected methods by subclassing a class from your class under test. In the subclass-for-test you can call the protected methods without any problem.

Hope that helps!

Bas

James Grenning

unread,
Feb 9, 2014, 1:09:05 PM2/9/14
to cppu...@googlegroups.com
Hi Shiva

You are getting a lot of advice about not using friend.  I agree.  Also, what you are suggesting is not really practical.  Friendship is granted one class to another.  Friendship cannot be inherited.  So each TEST would have to be mentioned in the class under test that has the private members, not just the TEST_GROUP.  That would be a pretty nasty test smell.

I agree with Martin and Bas. Friend is not needed, ever. It should not be in the definition of C++ IMO.

#define private public is a good intermediate workaround during legacy refactoring.  Not a long term fix.  I agree with the others that suggest that your code (that needs to have private functions tested directly) should be refactored to not need it.

Another legacy code technique is to change the visibility of privates to protected, then subclass the CUT and call what you need.

Bas, thanks for the credit on Legacy code == tests without code.  I stole it from Michael Feathers.

thanks, James

--------------------------------------------------------------------------------------------
James Grenning Author of TDD for Embedded C


James Grenning

unread,
Feb 9, 2014, 1:52:35 PM2/9/14
to cppu...@googlegroups.com
Hi Andy

Maybe friend could have been avoid here too.  Rather than subclassing, I'd prefer delegating to an interface class that has the virtual functions, separating state machine from the actions needing to be performed on the specific FET.

From what you are saying it seems that the design could have been improved applying the single responsibility principle, separating the state machine responsibility from the FET actions.

As it is, it sounds like to test the FET code, you needed the state machine.  With this separation, the FET code and  state machine can be tested independently.  


--------------------------------------------------------------------------------------------
James Grenning Author of TDD for Embedded C


Reply all
Reply to author
Forward
0 new messages