Creating custom mater for unit testing in Jasmine 2.0

Recently I encountered the need to write a custom matchmaker in jasmine. The first thing I started googling and found an example where everything is clearly and clearly explained. Actually the code is presented below:

describe('Hello world', function () {
    beforeEach(function() {
        this.addMatchers({
            toBeWithinOf: function(distance, base) {
                this.message = function() {
                    var lower = base - distance,
                           upper = base + distance;
                    return "Expected " + this.actual + " to be between " +
                        lower + " and " + upper + " (inclusive)";
                };
                return Math.abs(this.actual - base) <= distance;
            }
        });
    });
    it('should be within in range', function () {
        expect(8).toBeWithinOf(2, 6);
    });
});


In this example, a matcher is created that will report whether the entered number ( this.actual ) is in a certain interval. Note, when calling the match, two parameters are passed: base - the number from which will be measured on both sides, a certain value - distance , eventually forming the search interval - [base - distance, base + distance] . In this case, we expect 8 to be in the interval [4, 8]. If the user-specified number is outside the interval, then in the tests we will see the error that we generate using the this.message function .

Everything seems to be nothing, but when running the example in jasmine 2.0 none of this works. It turns out that the syntax has changed a bit.

I tried a bunch of ways and having climbed more than one forum, I was able to solve this issue. The solution code is as follows:

describe('Hello world', function () {
    beforeEach(function () {
        jasmine.addMatchers({
            toBeWithinOf: function () {
                return {
                    compare: function (actual, distance, base) {
                        var lower = base - distance,
                            upper = base + distance,
                            result = {
                                pass:  Math.abs(actual - base) <= distance
                            };
                        if(!result.pass) {
                            result.message =  "Expected " + actual + " to be between " +
                            lower + " and " + upper + " (inclusive)";
                        }
                        return result;
                    }
                }
            }
        })
    });
    it('should be within in range', function () {
        expect(8).toBeWithinOf(2, 6);
    });
});

As you can see, the method for calling the function to add matchers has been changed - ( this.addMatchers -> jasmine.addMatchers ). Also, from the function itself, we are forced to return an object in which the compare method should be declared , which takes all the parameters, and not the match function itself.

Please note that the first parameter ( actual ) corresponds to the number that we want to check, and if we need to transfer our parameters to the player itself (as in our case - base and distance), then you can specify them there.

Inside the compare function itself, we create an object into which we immediately write the comparison property ( pass ). And only if this property does not work out in the end, then only then is the property createdmessage , in which you can form the text that the user will see when the test fails.

A link to a working example can be found here - fiddle .

That's all.

Also popular now: