Search code examples
c++unit-testingtestingmockinggoogletest

How to unit test if a private variable has changed


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?


Solution

  • 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.