I often find that I would like to test a class at a finer grain than its public interface. Currently, I am using preprocessor directives in the class to be tested:
#ifdef TEST
public:
#else
protected:
#endif
I don't want to make the protected interface public just so that my test code runs, but I don't know a good way to use 'friend' to solve this problem and the directives sure make the class code ugly. Maybe a slick macro, but I would rather not have to touch the class code at all.
Does anyone have any thoughts on this?
Thanks in advance,
Jeremy
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
My feeling is that if the tests are meant to be intrusive, make them intrusive.
class MyClass
{
friend class MyClassTest
// stuff
};
class MyClassTest : public CppUnit::Test { };
AFAIAC, this class isn't meant for testing the interface of the class only. Sometimes you may wish to test just the interface, but I prefer testing each of the member functions with an intrusive mechanism like friendship. This has the benefit of also not using any preprocessor ugliness.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
When posting this question to an XP-forum, one of the answers was like this:
"If you want to test a private method, then your class probably has aspects that can be taken out and separated into a new class."
I take the need for testing a private/protected member as a "code smell". Refactoring always solved this problem for me and also resulted in a nicer structure.
Wolfgang
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2002-12-09
First of all, thanks for the feedback. Unfortunately, I am still searching...
The 'Testable' alias is similar to, but cleaner than what I have been using. My only gripe would be the name choice; it suggests that the public interface is not testable.
The friend solution is what I first considered, but I would like to avoid dependencies of system code on testing code.
I very much like the 'code smell' solution, but I'm not sure how to refactor my code as it is already quite reduced. I have a public 'Step(...)' function that is called each "step" which, in turn, calls a list of protected functions (that may very between steps). I could make all of the functions public to the client, but this would complicate thier code and I see no good reason to expose the protected interface.
Thanks again for the input. I will meditate on this :)
Jeremy
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
from your short description I would guess that you have a state-machine and the states in one class?(or is it: container and iterator?)
Do you know the state-machine-compiler (SMC) project at sourceforge? (smc.sourceforge.net)
Wolfgang
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
using _TESTCASECODE as an identifier is a violation of the rules of the C++ language. For more information on this and how to make template classes friends (I don't know how to do that off hand), ask on comp.lang.c++.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I often find that I would like to test a class at a finer grain than its public interface. Currently, I am using preprocessor directives in the class to be tested:
#ifdef TEST
public:
#else
protected:
#endif
I don't want to make the protected interface public just so that my test code runs, but I don't know a good way to use 'friend' to solve this problem and the directives sure make the class code ugly. Maybe a slick macro, but I would rather not have to touch the class code at all.
Does anyone have any thoughts on this?
Thanks in advance,
Jeremy
We use a similar technique but use an alias defined in a standard types header:
#ifdef _DEBUG
# define Testable public // opened for testing
#else
# define Testable // closed for release
#endif
In the code :
#include "OurStdTypes.h"
class ToTest
{
public:
// public interface
private:
// always private
Testable:
// open for testing only
}
Haven't found a less intrusive mechanism but would love to see one..
We use a similar technique but use an alias defined in a standard types header:
#ifdef _DEBUG
# define Testable public // opened for testing
#else
# define Testable // closed for release
#endif
In the code :
#include "OurStdTypes.h"
class ToTest
{
public:
// public interface
private:
// always private
Testable:
// open for testing only
}
Haven't found a less intrusive mechanism but would love to see one..
Wow, that's something. :)
My feeling is that if the tests are meant to be intrusive, make them intrusive.
class MyClass
{
friend class MyClassTest
// stuff
};
class MyClassTest : public CppUnit::Test { };
AFAIAC, this class isn't meant for testing the interface of the class only. Sometimes you may wish to test just the interface, but I prefer testing each of the member functions with an intrusive mechanism like friendship. This has the benefit of also not using any preprocessor ugliness.
When posting this question to an XP-forum, one of the answers was like this:
"If you want to test a private method, then your class probably has aspects that can be taken out and separated into a new class."
I take the need for testing a private/protected member as a "code smell". Refactoring always solved this problem for me and also resulted in a nicer structure.
Wolfgang
First of all, thanks for the feedback. Unfortunately, I am still searching...
The 'Testable' alias is similar to, but cleaner than what I have been using. My only gripe would be the name choice; it suggests that the public interface is not testable.
The friend solution is what I first considered, but I would like to avoid dependencies of system code on testing code.
I very much like the 'code smell' solution, but I'm not sure how to refactor my code as it is already quite reduced. I have a public 'Step(...)' function that is called each "step" which, in turn, calls a list of protected functions (that may very between steps). I could make all of the functions public to the client, but this would complicate thier code and I see no good reason to expose the protected interface.
Thanks again for the input. I will meditate on this :)
Jeremy
Hi Jeremy,
from your short description I would guess that you have a state-machine and the states in one class?(or is it: container and iterator?)
Do you know the state-machine-compiler (SMC) project at sourceforge? (smc.sourceforge.net)
Wolfgang
The suggestion from Tom Plunket look nice but how do I accomplish it with CppUnit.
My test class is declare like:
template<typename T> class TestCMyClass(T t);
I tried something like this:
class CMyClass
{
#ifdef _TESTCASECODE
template<typename T> friend class TestCMyClass(T t);
#endif
using _TESTCASECODE as an identifier is a violation of the rules of the C++ language. For more information on this and how to make template classes friends (I don't know how to do that off hand), ask on comp.lang.c++.