Accessing private members in unit tests?

Started by
6 comments, last by Mike Bossy 18 years, 8 months ago
I've just started diving into unit testing using cxxtest and I can't find anything on have to access a private member of a class through the testing frameworks. Is there a good way to go about doing this?
Advertisement
From what I've read, you're not meant to. The opinion seems to be that if the private implementation details are complicated enough to warrant testing then you should refactor.

p.s. on a related note: a series of pretty good articles on TDD
Two other options are built directly into the C++ language. You can make the test framework classes friends of your classes, or you can make your private data protected, and then derive classes which are meant to interact with the test framework. I've used both examples in production.

Though I tend to agree with lucky_monkey's aforementioned philosophy.
Jeromy Walsh
Sr. Tools & Engine Programmer | Software Engineer
Microsoft Windows Phone Team
Chronicles of Elyria (An In-development MMORPG)
GameDevelopedia.com - Blog & Tutorials
GDNet Mentoring: XNA Workshop | C# Workshop | C++ Workshop
"The question is not how far, the question is do you possess the constitution, the depth of faith, to go as far as is needed?" - Il Duche, Boondock Saints
The testing framework that's part of Microsoft Team System uses reflection in order to test and access private methods and variables. Obviously, this is applicable only to managed languages, and the wisdom of it is clearly debatable even there.
--AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.[Project site] [IRC channel] [Blog]
I know I'm going to die a slow and painful death for even suggesting this...

#define private public
#define protected public
#define class struct

It's horrible, but so long as you only have it defined that way when your testing is happening, then it shouldn't be such bad karma. [And it will allow you to actually test the code you're wanting to test]...

[Though I wouldn't nessecarily say that this is a good thing, I've seen it in a few commercial products, for example, the Doom 3 SDK]...

[edited: Thanks, MaulingMonkey - Addition of class struct define]

--CJM

[Edited by - CJM on August 8, 2005 4:50:37 AM]
Quote:#define private public
#define protected public

*Chuckle*
I need to remember you can do that kind of stuff. Then never do it.
Quote:Original post by CJM
I know I'm going to die a slow and painful death for even suggesting this...

#define private public
#define protected public


You frogot:

#define class struct

Without this, it is still possible to have private data:

class foo {    int bar; //private, the default setting for a class};


Oh, and: *pokes you with a sharp, deadly stick, the jab of which will eventually kill you in a most gruesome fashion*


In my opinion, tests should not inspect the implementation details of a class - this is brittle and will break your tests the moment you change any aspect of the implementation, which is one of the most crucial times for a test to work - to ensure the interface has not changed. It does not work well with test driven development either, as you will be attempting to write tests to rely upon implementation details prehaps not yet even concieved. Instead, prefer to thoroughly test the outside interface. If any of the internals are complicated enough to warrent a test, they likely belong in their own (sub)class which in turn can be tested. This subclass would need implement a public interface for the original to use of course, which would be what is tested. These details are then hidden from the user of the original class by making the subclass either a protected or private member, or protected/privately inherited.

For what it's worth, this is simply my opinion. One that I think people would be crazy for disagreeing with, but still just my opinion nonetheless - and I know a lot of people I consider crazy ;-).
Thanks to everyone for their replies and hacks :) I think approaching unit testing almost as black box testing makes sense. You want to know what you get out is valid depending on what goes in, you don't necessarily need to know that interim steps were successful. With that in mind I'm going to ignore private members for now until I see a drastic need to hit them separately.

This topic is closed to new replies.

Advertisement