How to unit test if a private variable has changed - c++

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?

Short answer: Dont do it.
Your test should test against the public interface only. Let me try to explain with some code:
class Adder {
int a,b;
public:
Adder() : a(0),b(0) {}
void set(int x,int y) { a=x;b=y; }
int get() { return a+b; }
};
and a test (assume for a moment we had access to a and b):
void testAdder(){
Adder add;
int a = 1;
int b = 2;
add.set(a,b);
ASSERT_EQUALS(add.a,a);
ASSERT_EQUALS(add.b,b);
ASSERT_EQUALS(add.get(),a+b);
}
Suppose you already distributed the code and someone is using it. He would like to continue using it but complains about too much memory consumption. It is straightforward to fix this issue while keeping the same public interface:
class Adder {
int c;
public:
Adder() : c(0) {}
void set(int x,int y) { c = x+y; }
int get() { return c; }
};
That was easy, but the test will fail :(
Conclusion: Testing private implementation details defeats the purpose of testing, because each time you modify the code it is likely that you also have to "fix" the test.

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.

A few options I can think of:
1) Make the test code a friend of the class. That way it can access the private members.
2) Add a getter to the class that's under a #ifdef Testing directive that only gets defined when building the test version (or put public: under that macro and a private: in the #else branch).
3) #define private public when building the test (no, not really).
4) Use gcc's -fno-access-control flag when building the version to test, so that everything is public (if you are using gcc that is).
5) Just give up testing externally from the class and instead add relevant static_asserts/asserts to the class itself to test invariants.
6) Don't. Just stick to testing the public interface.
Hope that helps :-)

Related

Calling private member of inherited class for unittest

I'm trying to write a unittest but I'm running into some problems.
I've got a class which has an int to keep track of the current state. All classes that are inherited of this class can change the state by calling the protectedFunction.
class RandomClass
{
public:
RandomClass()
{
mState = 0;
}
protected:
void protectedFunction()
{
++mState;
}
private:
int mState;
friend void UNITTEST_setMState(int state);
friend int UNITTEST_getMState();
};
Now i'd like to write a unittest for this class. So I created a new class which inherits the previous class. To Properly test all the states I need to set the state, and I need to get the state to assert it. I've tried using a friend function but it does not seem to work.
class UnittestRandomClass : public RandomClass
{
public:
void wrapperProtectedFunction()
{
protectedFunction();
}
void UNITTEST_setMState(int state)
{
this->mState = state; // Apparently not like this
}
int UNITTEST_getMState()
{
return this->mState; // Apparently not like this
}
};
int main() {
UnittestRandomClass ut;
ut.UNITTEST_setMState(1);
ut.wrapperProtectedFunction();
int res = ut.UNITTEST_getMState();
ASSERT_EQ(res, 2);
}
I seem to be doing something wrong, as the mState still appears to be private and thus I'm getting an inaccessible error. I've also tried calling it directly by just returning mState, but the same error applies.
One solution would be to move the mState to protected, but as there are other classes which inherit the RandomClass, I do not think that would be a save solution.
So how would I be able to solve such an issue and resolve my errors?
For future viewers here is the working code:
class RandomClass
{
public:
RandomClass()
{
mState = 0;
}
void publicFunction();
protected:
void protectedFunction()
{
++mState;
}
private:
int mState;
friend class UnittestRandomClass;
};
class UnittestRandomClass : public RandomClass
{
public:
void wrapperProtectedFunction()
{
protectedFunction();
}
void setMState(int state)
{
mState = state;
}
int getMState()
{
return mState;
}
};
int main() {
UnittestRandomClass ut;
ut.setMState(1);
ut.wrapperProtectedFunction();
int res = ut.getMState();
ASSERT_EQ(res, 2);
}
Your class declares a free-standing function to be friend.
Your unit test uses a member function of a class, the class is not declared friend.
You can write friend class UnitTestRandomClass;
Specifically, what you want to do, make a member function of a future derived class a friend is not provided by the standard. There is no syntax for that.

Dont allow access to member variable directly within same class

I am not sure is my question is right or not? But let me still try to ask once.
I have a Class with have few member variables defined. As per OO concepts, every member function can access , all member variables of its class.
But I want these member variable to be accessed via specific methods (Lets say Getters) , even within same class member functions.
It there any way to do it?
class A {
public:
void func1();
void func2();
B getB();
private:
B b;
}
void A::func1() {
b.functionFromB(); // function uses member variable b directly
}
void A::func2() {
B b1=getB(); // function ask for B from a function and then uses it. // I need something like this... And ensure each function uses same way otherwise there should be warning...
b1.functionFromB();
}
Thanks,
Kailas
No, there is not. You can do it via encapsulation and inheritance like:
class shape
{
private:
int angles;
protected:
shape(int angles_):angles(angles_){};
int getAngles() const;
}
class square : private shape
{
public:
square():shape(4){}
void doSth()
{
\\ you can access angles only via getAngles();
}
}
Any private members of the class can be accessed from within the class, but not by users of the class. So it looks like you need private members and public methods that allow access to them.
class A
{
private:
int a;
public:
int getA() {return a;}
};
int main()
{
A inst;
int t;
inst.a =5; // error member a is private
t = inst.getA(); //OK
}
The concept extends fine to nested class declarations in case you only want to allow instance of a class to be created from another class; details here
As others have said - you have to add an additional layer.
If you want to give access to specific methods then you can use the friend keyword. E.g.
// Public.h
#pragma once
class Public
{
public:
Public();
int GetI() const;
float GetF() const;
private:
std::unique_ptr<Private> p_;
};
//Public.cpp
#include "Public.h"
Public::Public()
: p_(new Private)
{
}
int Public::GetI() const
{
return p_->i_;
}
float Public::GetF() const
{
return p_->f_;
}
// Private.h
#pragma once
class Private
{
friend int Public::GetI() const;
friend float Public::GetF() const;
int i_;
float f_;
};
Keep in mind that every friend method can access ALL private members.
If you really really want to limit which methods can access which members then you can wrap each member in a separate class/struct and make only the getter/setter of that member a friend of that class/struct but I would not recommend this approach.

Writing Gameboy emulator in C++, how to test opcodes (Google Test Framework)?

I'm trying to write GameBoy emulator, but I'm not sure how should I test my CPU_LR39502 class. To avoid huge if-else-if / switch-case statements, I came up with idea to put opcode functor into map, which takes opcode as key:
class Functor
{
std::function<void()> m_function;
public:
Functor(std::function<void()>&& function)
{
m_function = std::move(function);
}
void operator()()
{
m_function();
}
};
class BaseOpcodeFunctor : public Functor
{
unsigned char m_opcode;
std::string m_disasmString;
public:
BaseOpcodeFunctor(std::function<void()>&& function,
unsigned char opcode,
std::string&& disasmString)
: Functor(std::move(function)),
m_opcode(opcode),
m_disasmString(std::move(disasmString)) {}
std::string disasm()
{
return m_disasmString;
}
unsigned char getAssignedOpcode()
{
return m_opcode;
}
};
And example of it:
class CPU_LR35902
{
...
std::map<unsigned char, BaseOpcodeFunctor> m_baseOpcodeMap;
public:
CPU_LR35902()
{
...
initializeBaseOpcodeMap();
}
...
private:
void addFunctorToBaseOpcodeMap(BaseOpcodeFunctor&& functor);
void initializeBaseOpcodeMap()
{
...
addFunctorToBaseOpcodeMap(BaseOpcodeFunctor([this]() {
bitwiseRotationLeft(REGISTER_A);
}, 0x07, "RLCA"));
}
void bitwiseRotationLeft(LR35902_8BIT_REGISTERS reg)
{
resetFlag(FLAG_Z);
resetFlag(FLAG_N);
resetFlag(FLAG_H);
setFlag(FLAG_C, registers_8bit.at(reg) >> 7);
registers_8bit.at(reg) <<= 1;
registers_8bit.at(reg) |= getFlag(FLAG_C);
}
...
};
And this somehow makes me think about two problems. I actually wanted to write implementation of opcode immediately when adding it to m_baseOpcodeMap, but to make it testable, I wrote implementation as a member function (here bitwiseRotationLeft as example) and I call it in lambda - and I'm not sure if this is correct approach.
Currently, to test some implementations, I've got something like this (using google test framework):
#include "cpu_lr35902.h"
#include <gtest/gtest.h>
class CPUTest : public ::testing::Test
{
protected:
CPU_LR35902 cpu_testable;
};
TEST_F(CPUTest, test_bitwiseRotationLeft)
{
cpu_testable.flags = 0;
cpu_testable.clearRegisters();
//0xA5 = 1010 0101, after: 0100 1011 = 0x4B
cpu_testable.registers_8bit.at(CPU_LR35902::REGISTER_A) = 0xA5;
cpu_testable.bitwiseRotationLeft(CPU_LR35902::REGISTER_A);
ASSERT_EQ(1, cpu_testable.getFlag(CPU_LR35902::FLAG_C));
ASSERT_EQ(0x4B, cpu_testable.registers_8bit.at(CPU_LR35902::REGISTER_A));
}
but to get access to private members of CPU_LR35902, I have to add
FRIEND_TEST(CPUTest, test_name);
in CPU_LR35902 class - after that I can reach private members of tested class in TEST_F, but I can't access them in CPUTest class (for SetUp / TearDown). Considering the fact, that I've got a little bit more of tests and I'm going to have a plenty of them, I think that adding FRIEND_TEST for every test makes everything somehow bad-looking. I'm in touch with C++ for some time, but I've got completely zero experience in using Google Test Framework and my intuition tells me that there must be a better way to do it. Any clues will be gladly appreciated :)
How do I test private class members without writing FRIEND_TEST()s?
Write the tests as members of the fixture class:
class Foo {
friend class FooTest;
...
};
class FooTest : public ::testing::Test {
protected:
...
void Test1() {...} // This accesses private members of class Foo.
void Test2() {...} // So does this one.
};
TEST_F(FooTest, Test1) {
Test1();
}
TEST_F(FooTest, Test2) {
Test2();
}
This makes it so you only have to friend one class per test fixture, without the need of including gtest in your header (or your project).
You can also just make a normal class that is a friend of the main class that is purely used by tests to access private members.
class Foo {
friend class FooTesting;
...
};
class FooTesting {
public:
static int read_private_variable1( Foo& );
};
TEST_F(FooTest, Test1) {
Foo bar;
EXPECT_EQ( FooTesting::read_private_variable1( bar ), 5 );
}
Probable not the answer your looking for but you could conditional make the cpu params public for testing
class CPU_LR35902
{
...
public:
...
#ifndef TESTING_CPU
private:
#endif
...
};

Accessing private variables through levels of classes.

So in my current understanding of how to use encapsulation correctly it is a good rule of thumb to make variables private and access them through member functions of the class like this:
class Aclass{
private:
int avar;
public:
void ch_avar(int val){avar = val};
int get_avar() {return avar;}
};
My question is how would I access a private member of a class instance which is its self a private member of another class. Here is an example of the way I have been trying to do it (not retyping the example above for brevity)
class LargerClass{
private:
int other_var;
Aclass A; //has two instances of class "Aclass"
Aclass B;
public:
void ch_other_var(int val){other_var = val;}
int get_other_var() {return other_var;}
// this is the important line for the question
int get_avar(Aclass X){return X.get_avar();}
};
Now In my real program there are a few more levels of this and I keep getting the compilation error that "Aclass" is an unknown type. Even though I have included the header file for Aclass in the Larger class. Since I am stuck I thought It would be good to find out if this is even the correct (or an acceptable way) of doing what I want. I am new to OOP and this feels sloppy to me.
To access the private member of a class instance which is its self a private member of another class, can be done this way. You don't need to pass a Aclass X. It is unneccessary. You can call it by the instance name you have given..
class LargerClass{
private:
int other_var;
Aclass A; //has two instances of class "Aclass"
Aclass B;
public:
void ch_other_var(int val){other_var = val;}
int get_other_var() {return other_var;}
// this is the important line for the question
int get_avar_A(){return A.get_avar();}
};
If you have 20 instances of Aclass, rather you create a vector of Aclass instances.
class LargerClass{
private:
int other_var;
Aclass A[20];
public:
void ch_other_var(int val){other_var = val;}
int get_other_var() {return other_var;}
// this is the important line for the question
int[] get_avar_A()
{
int other_var[20];
for(int i= 0; i<20; i++)
{
other_var[i] = A[i].get_avar();
}
return other_var;
}
};

Enforce use of Getter / Setter within same class (C++)

Is there a way in C++ to enforce the use of getters or setters WITHIN the class?
class C{
private:
int x; // should only be Changed by setX();
private:
setX(int i){
(...) // enforce some complicated invariantes
x = i;
};
m(){
x = 5; // should not not allowed
}
}
The only thing that comes to my mind is to put all the super-private members as private variables into an abstract base class with protected getters/setters.
But that doesn't sound like good practice.
Are there any more common ways or conventions to ensure, that everyone uses the setters?
(My purpose:
If the class gets bigger i find it hard to remember what variables carry invariants with them. And currently before setting any variable I search, whether I created a getter or setter (to find out whether i have to consider invariants). But i want to get rid of this unprofessional searching-each-time.)
You can take advantage of composition like this:
class C_int
{
public:
void setX(int i)
{
/* enforce invariants */
x = i;
}
private:
int x;
};
class C
{
pulbic:
void m()
{
x.setX(5);
// x.x = 5; // Won't compile.
}
private:
C_int x;
};
But I find it odd that this is an actual problem for you, IMHO. You're the writer of the C class and its members. You have control over how the x variable is read/written, and x is not part of the public interface of the class. While it is true that other people (e.g. maintainers) can write code that breaks invariants in the future, unit tests should be able to cover those cases.
a) favor accessors throughout your codebase for consistency. then you will more easily spot direct accesses to members. if you need special accessors, then create special methods:
void setFoo(const t_foo& foo) {
assert(foo.isValid());
this->d_foo = foo;
}
void invalidateFoo() {
this->d_foo = t_foo::InvalidFoo();
}
b) to get to an answer: i'll often create an inner class (temporarily in some cases):
class C {
class t_inner {
public:
/* ... */
void setX(int arg) {
/* enforce some complicated invariants... */
this->x = arg;
}
const int& getX() const {
/* ... */
return this->x;
}
private:
int x;
};
public:
/* ... */
private:
/* ... */
void m() {
this->inner().setX(5);
}
private:
t_inner d_inner;
};
The clean answer is No. There is no language feature for that; you can do some variation to achieve it, but that will clutter your code.
In Visual C++, __declspec( property ) can be used to have this feature:
__declspec(property(put=setFunction, get=getFunction)) data-type property-name;
See this article