In which I argue it might sometimes be useful to test private/protected methods, and demonstrate how to do it in a framework-independent way.
How do you test private/protected functions? The most common, and often correct answer is “Don’t!”. But sometimes it can be useful, especially when test-driving helper-methods. Example:
class Ohlson { protected: int helper(); //We want to test this public: int compute() { //(...) int n = helper(); //(...) } }; TEST(TestOhlson, helper_returns42) { Ohlson o; ASSERT_EQ(42, o.helper()); }
This will fail: error: ‘int Ohlson::helper()’ is protected
. Many unittesting frameworks provide a way to work around this, like googletest’s FRIEND_TEST, but there is a way to get around this in normal C++, by subclassing to modify visibility.
In C++, a subclass can change the visibility of a derived function. This is not possible in Java or C# as far as I know, and to be honest it does sound somewhat dangerous. But C++ wasn’t made to keep you in a padded box with a helmet on, was it?
Here’s how you do it:
class OhlsonForTest : public Ohlson { public: using Ohlson::helper; };
And voilà, helper()
is now public and can be tested:
TEST(TestOhlson, helper_returns42) { OhlsonForTest o; ASSERT_EQ(42, o.helper()); }
This trick can be useful in some situations, but when you are done, see if you might refactor your way out of the problem instead.
And I would be extremely sceptical to do anything like this in production code!
By the way, this trick is often useful in combination with last weeks technique on Making a Derived Class to Allow Testing an Abstract Class.
If you enjoyed this post, you can subscribe to this blog, or follow me on Twitter
Good tip! This solves one of the problems I always seem to run into when writing tests.
This also works for Java, you can always increase the visibility of subclasses (but not decrease).
By increasing the visibility, do you mean override and delegate? Or modify the visibility of the actual parent method? Can you give an example?
From a Facebook comment: “This is how we do it in C# as well”
I get the impression that you really can’t, you can only approximate by overriding the method and delegating to the parent. But I don’t know C#, so any code examples would be great!