I am trying to do unit testing (using the Boost unit testing framework) on a C++ class called VariableImpl
. Here are the details.
class Variable { public: void UpdateStatistics (void) { // compute mean based on m_val and update m_mean; OtherClass::SendData (m_mean); m_val.clear (); } virtual void RecordData (double) = 0; protected: std::vector<double> m_val; private: double m_mean; }; class VariableImpl : public Variable { public: virtual void RecordData (double d) { // put data in m_val } };
My question is how can I check that the mean is computed correctly? Note that 1) m_mean
is protected and 2) UpdateStatistics
calls a method of another class and then clears the vector.
The only way I can see would be to add a getter (for instance, GetMean
), but I don't like this solution at all, nor I think it is the most elegant.
How should I do?
And what should I do if I were to test a private method instead of a private variable?
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.
A unit test should test the public contract, the only way how a class could be used in other parts of the code. A private method is implementation details, you should not test it; as far as public API works correctly, the implementation doesn't matter and could be changed without changes in test cases.
To test private methods, you just need to test the public methods that call them. Call your public method and make assertions about the result or the state of the object. If the tests pass, you know your private methods are working correctly.
Well, unit testing should test units and ideally every class is a self-contained unit – this follows directly from the single responsibility principle.
So testing private members of a class shouldn’t be necessary – the class is a black box that can be covered in a unit test as-is.
On the other hand, this isn’t always true, and sometimes with good reasons (for instance, several methods of the class could rely on a private utility function that should be tested). One very simple, very crufty but ultimately successful solution is to put the following into your unit-test file, before including the header that defines your class:
#define private public
Of course, this destroys encapsulation and is evil. But for testing, it serves the purpose.
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