Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unit test a function which only changes internal state

Assume the following class

class Observable() {
    constructor() { this._cbs = []; }

    on(cb) {
        this._cbs.push(cb);
    }

    off(cb) {
         this._cbs.splice(this._cbs.indexOf(cb));
    }

    trigger() {
        this._cbs.forEach((cb) => cb());
    }
}

How should I unit test the on method. Now I could inspect the this._cbs array and simply verify that the callback is pushed onto it. But if I do that I apply implementation knowledge to my tests. Or I could spyOn the callback and call trigger and check if the callback is called or not. However, this is not an integration test.

So in general, what would be the approach to unit test function which only have internal effects ?

like image 221
Jeanluca Scaljeri Avatar asked Sep 05 '26 18:09

Jeanluca Scaljeri


2 Answers

I think that if your method only changes internal state, the only way to verify that would be through publicly accessible methods (e.g. if your class had a .count() function you could check that afterwards.)

Without an external mechanism to verify the internal operation it's very hard to check.

Sometimes in C# if this was really important logic, I'd use the [InternalsVisibleTo] attribute to check (in you case _cbs) the internal state of the class.

Alternatively if this was not very important functionality it may be sufficient to know that a function was called. So in that example you might provide a mocked _cbs as a parameter and check that .push() was called.

like image 122
dougajmcdonald Avatar answered Sep 07 '26 08:09

dougajmcdonald


In this case your aggregate is the class Observable, which has an invariant called _cbs. Now the only business value that you could test your System Under Test against is the business logic that accesses the invariant -that changes the state of the observable system-, that is to assert the outcome of the flow of the called business logic.

like image 42
kayess Avatar answered Sep 07 '26 08:09

kayess



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!