Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a friend class vs. adding accessors for unit testing in C++?

Is it better to add functions that return the internal state of an object for unit testing, as opposed to making the testing class a friend? - especially, when there is no use for the functions except for the case of unit testing.

like image 757
bias Avatar asked Jul 19 '09 04:07

bias


2 Answers

Unit tests should 95% of the time only test the publicly exposed surface of a class. If you're testing something under the covers, that's testing implementation details, which is inherently fragile, because you should be able to easily change implementation and still have the tests work. Not only is it fragile, but you could also be tempted into testing things that aren't actually possible in planned usage scenarios, which is a waste of time.

If the point of the accessors you want to add is just to test whether the function had the desired effect, your class design may violate another principle, which is that a state-machine-like class should always make it clear what state its in, if that affects what happens when people interact with the class. In that case, it'd be right to provide those read-only accessors. If it doesn't affect the class's behavior, refer back to my previous bit about implementation details.

And as you rightly said, cluttering up the public surface of a class with unused stuff is also undesirable for its own reasons.

If I had to pick between accessors and friending in your case, I would choose friending, simply because you own your test and can change it in a pinch. You may not own the code by the clown who finds a way to use your extra accessors, and then you'll be stuck.

like image 133
Drew Hoskins Avatar answered Sep 19 '22 20:09

Drew Hoskins


I'll disagree with the accepted answer and instead recommend the use of a friend class.

Part of the state you are testing is probably specific to the implementation of your class; you're testing details that other code normally doesn't know about or care about and shouldn't rely on. Public accessor functions make these implementation details part of the class's interface. If the internal state you are testing is not part of the intended interface, it shouldn't be visible through public functions. From a purist point of view you're stuck between two wrong answers, as friend classes are also technically part of the public interface. In my mind the question becomes, which option is less likely to lead to poor coding choices down the road? Going with a set of implementation-dependent public accessor functions will inadvertantly encourage an implementation-dependent conceptual model of the the class, leading to implementation-dependent use of the class. A single friend class, appropriately named and documented, is less likely to be abused.

While in general I strongly agree with the recommendation to prefer accessor functions over direct access to member variables, I don't agree that this best practice applies to unit testing of implementation-dependent internal state. A reasonable middle ground is to use private accessor functions to those pieces of state your unit test will care about, and be disciplined enough to use the accessor functions in your unit tests. Just my opinion.

like image 42
Darryl Avatar answered Sep 18 '22 20:09

Darryl