Search code examples
javascripttestingjasminematcher

How to write a Jasmine custom matcher


I am trying to write a Custom Matcher that tests if a string contains a special number of occurrences of a different string. This is what I did.

var matcher = {
    toContainTimes: function (expected, num) {
        return {
            compare: function(actual){
                actual.match(new RegExp(expected, "g") || []).length == num;
            }
        }
    }
}

But I get an error when executing this:

TypeError: Cannot read property 'pass' of undefined

My test looks like this:

expect(queryString).toContainTimes("&", 2);

It should return true if the string "&" occurs exactly twice in queryString. What did I do wrong?


Solution

  • From Jasmine docs:

    The compare function must return a result object with a pass property that is a boolean result of the matcher. The pass property tells the expectation whether the matcher was successful (true) or unsuccessful (false).

    You should return an object with such properties declared.

    Try this:

    var matcher: {
        toContainTimes: function () {
            return {
                compare: function(actualValue, expectedResult){
                    var expected = expectedResult[0];
                    var num = expectedResult[1];
                    var result = {
                        pass: true,
                        message: ''
                    }
                    result.pass = actualValue.match(new RegExp(expected, "g") || []).length === num;
    
                    if(!result.pass)
                        result.message = 'insert error message here. this will shown when the jasmine spec failed';
    
                    return result;
                }
            }
        }
    }
    

    Usage: expect(queryString).toContainTimes(["&", 2]);