Search code examples
c++unit-testinggoogletest

Is it normal to change methods behaviour to test them?


I have a class:

class MotorControl
{
    private:
        IAccelStepper *motor;
        IEncButton2<EB_ENCBTN> *encoder;
    
    public:
        void processEncoder();
        void returnToOrigin();
        void switchStep();
};

And its method that I want to test:

void MotorControl::processEncoder()
{
    if (encoder->held())
        returnToOrigin();
    else if (encoder->click())
        switchStep();
}

In my test, I want to know if the method (e.g. returnToOrigin()) was called. I know about mocks but I dont need to mock entire class so I can't write interface and mock it. GoogleTest API explained how to mock non-vurtual methods, but it requires to add a template. Also I had an idea to make this function non-void (e.g. int) and return something in every case.

I'm curious to know if it is a normal practice to expand(change) behaviour of your class only for tests. Maybe instead of mocking part of its method I should control output state, but if some method uses a lot of parameters is it normal to check every? I'd appreciate any help and advices.


Solution

  • I'm curious to know if it is a normal practice to expand(change) behaviour of your class only for tests

    No, if by this you mean that your method would have a different behavior, logic or implement a different algorithm when ran through a test versus normal operation.

    Yes, if by this you mean change the method syntax or api so that it can be properly tested.

    For example even though in your app you only use one type of motor and one type only, it's not only acceptable but recommended to create a motor interface (*) so that you can mock operations on motors. This doesn't change the way the methods work in test vs non-test env, but it does change their signature to operate on interface instead of concrete types.

    *) I use interface here as an example, but it really depends on the testing framework, it can be interfaces with virtual methods, or templates or whatever the testing framework requires.