Let's say that I have this class in C++:
class ExampleClass{
private:
int example_var;
public:
void exampleMethod(){
example_var = other_value; // other value will be always different
}
}
How can I unit test exampleMethod()
? I would like to do something like this:
void testExampleMethod(){
ExampleClass obj;
int before_call_value = obj.example_var;
obj.exampleMethod();
int after_call_value = obj.example_var;
ASSERT_NOT_EQUALS(before_call_value, after_call_value);
}
But example_var
is private.
So, what is the right way to do this unit test? How can I test if a private example_var
has changed?
Why We Shouldn't Test Private Methods. As a rule, the unit tests we write should only check our public methods contracts. Private methods are implementation details that the callers of our public methods are not aware of. Furthermore, changing our implementation details should not lead us to change our tests.
The mangling rules are designed mostly to avoid accidents but it is still possible to access or modify a variable that is considered private.
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.
It is bad approach to test private variable/methods. But if you need there are a lot of options:
You can make Your test class as friend of ExampleClass
You can grab information using moc object
If you want to access example_val
, there are one of two things you can do. The first is by making testExampleMethod()
a friend method, as follows:
class ExampleClass{
private:
int example_var;
public:
void exampleMethod(){
example_var = other_value; // other value will be always different
}
friend void testExampleMethod(); //Now you can use the function as is.
}
On the other hand, you could just add a getter to your ExampleClass
to access the variable, such as the following:
class ExampleClass{
private:
int example_var;
public:
void exampleMethod(){
example_var = other_value; // other value will be always different
}
inline void getExampleVar() const { return example_var; }
}
And then change testExampleMethod()
to:
void testExampleMethod(){
ExampleClass obj;
int before_call_value = obj.getExampleVar();
obj.exampleMethod();
int after_call_value = obj.getExampleVar();
ASSERT_NOT_EQUALS(before_call_value, after_call_value);
}
I would honestly use the second method, since accessing a class's private variables is generally not recommended.
You just simply implement get
function for that private
variable you want to get.
class ExampleClass{
private:
int example_var;
public:
void exampleMethod(){
example_var = other_value; // other value will be always different
}
int GetExampleVar(){
return example_var;
}
}
And call it like
void testExampleMethod(){
ExampleClass obj;
int before_call_value = obj.GetExampleVar();
obj.exampleMethod();
int after_call_value = obj.GetExampleVar();
ASSERT_NOT_EQUALS(before_call_value, after_call_value);
}
Or make testExampleMethod
friend function
(friend function can access private variables of friend class even if its not its method).
class ExampleClass{
private:
int example_var;
public:
void exampleMethod(){
example_var = other_value; // other value will be always different
}
friend void testExampleMethod();
}
In my opinion first example would be more suitable, but if you cannot modify ExampleClass
, you can turn off access control for gcc
-- -fno-access-control
.
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