How do I unit test a protected method in C++?
In Java, I'd either create the test class in the same package as the class under test or create an anonymous subclass that exposes the method I need in my test class, but neither of those methods are available to me in C++.
I am testing an unmanaged C++ class using NUnit.
It is impossible to unit test private methods as their access level is specifically limits them from being accessed outside of the class where they reside. Changing the access modifier not to public but with less access is the only way possible to achieve this.
The easiest way would be to make sure your tests are in the same package hierarchy as the class you are testing. If that's not possible then you can subclass the original class and create a public accessor that calls the protected method.
Unit Tests Should Only Test Public Methods The short answer is that you shouldn't test private methods directly, but only their effects on the public methods that call them. Unit tests are clients of the object under test, much like the other classes in the code that are dependent on the object.
Assuming you mean a protected method of a publicly-accessible class:
In the test code, define a derived class of the class under test (either directly, or from one of its derived classes). Add accessors for the protected members, or perform tests within your derived class . "protected" access control really isn't very scary in C++: it requires no co-operation from the base class to "crack into" it. So it's best not to introduce any "test code" into the base class, not even a friend declaration:
// in realclass.h
class RealClass {
protected:
int foo(int a) { return a+1; }
};
// in test code
#include "realclass.h"
class Test : public RealClass {
public:
int wrapfoo(int a) { return foo(a); }
void testfoo(int input, int expected) {
assert(foo(input) == expected);
}
};
Test blah;
assert(blah.wrapfoo(1) == 2);
blah.testfoo(E_TO_THE_I_PI, 0);
You can also use using keyword to expose public block (using .
// in realclass.h
class RealClass {
protected:
int foo(int a) { return a+1; }
int foo(string a) { return a.length(); } // Overload works too
template<class T> int foo(const T& a) { return 1; } // Templates work too
};
// in test code
#include "realclass.h"
class RealClassExposed : public RealClass {
public:
using RealClass::foo;
};
RealClassExposed blah;
assert(blah.foo(1) == 2);
assert(blah.foo("test") == 4);
assert(blah.foo(blah) == 1);
See: http://en.cppreference.com/w/cpp/language/using_declaration
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With