In general, I agree with what others have said on here - only the public interface should be unit tested. Nevertheless, I've just had a case where I had to call a protected method first, to prepare for a specific test case. I first tried the #define protected public
approach mentioned above; this worked with Linux/gcc, but failed with Windows/VisualStudio. The reason was that changing protected
to public
also changed the mangled symbol name and thus gave me linker errors: the library provided a protected __declspec(dllexport) void Foo::bar()
method, but with the #define
in place, my test program expected a public __declspec(dllimport) void Foo::bar()
method which gave me an unresolved symbol error.
For this reason I switched to a friend
based solution, doing the following in my class header:
// This goes in Foo.h
namespace unit_test { // Name this anything you like
struct FooTester; // Forward declaration for befriending
}
// Class to be tested
class Foo
{
...
private:
bool somePrivateMethod(int bar);
// Unit test access
friend struct ::unit_test::FooTester;
};
And in my actual test case, I did this:
#include <Foo.h>
#include <boost/test/unit_test.hpp>
namespace unit_test {
// Static wrappers for private/protected methods
struct FooTester
{
static bool somePrivateMethod(Foo& foo, int bar)
{
return foo.somePrivateMethod(bar);
}
};
}
BOOST_AUTO_TEST_SUITE(FooTest);
BOOST_AUTO_TEST_CASE(TestSomePrivateMethod)
{
// Just a silly example
Foo foo;
BOOST_CHECK_EQUAL(unit_test::FooTester::somePrivateMethod(foo, 42), true);
}
BOOST_AUTO_TEST_SUITE_END();
This works with Linux/gcc as well as Windows/VisualStudio.