How to test if method has been called only once and not the second time in Jasmine?

I am testing mechanism that should call method once and prevent any subsequent calls with jasmine, I can see by attaching breakpoints that method is NOT being called second time however jasmine test fails. I would assume it has to do with spy not being designed to be used for multiple checks.
What would be proper solution to given situation?

JSfiddle of Code that is being tested I could not figure out how to do jasmine test jsfiddle properly (Jasmine version I am using is 1.3.1 while test template is on 1.2.0).

Test looks like this:

 it("Invoking OnPreQuery will add event listener for OnTheMoveViewPreLoad event. Triggering OnTheMoveViewPreLoad twice will call getChildrenForMasterRecordList only first time", function () {
            AddTreeSettingsObjectToBC({ bc: bc, Tree: { IncludeChildren: true} });
            ComposeMockPageObjWithObservableFieldsWithChildren();
            var preQuerySpy = spyOnEvent(onTheMove.PageDataRoles, 'OnPreQuery');
            $(onTheMove.PageDataRoles).trigger('OnPreQuery', { knockoutContextName: 'bc' });
            expect('OnPreQuery').toHaveBeenTriggeredOn(onTheMove.PageDataRoles);
            expect(preQuerySpy).toHaveBeenTriggered();
            var getChildrenForMasterRecordListSpy = spyOn(window, 'getChildrenForMasterRecordList');
            $(onTheMove.PageDataRoles).trigger('OnTheMoveViewPreLoad', { knockoutContextName: 'bc' });
            expect(getChildrenForMasterRecordListSpy).toHaveBeenCalled();
            $(onTheMove.PageDataRoles).trigger('OnTheMoveViewPreLoad', { knockoutContextName: 'bc' });
            expect(getChildrenForMasterRecordListSpy).not.toHaveBeenCalled();
        });

Code that is being tested:
HTML

<div data-role="page"></div>

Javascript

var onTheMove = function(){};
$.extend(onTheMove,{
    NullValue : "null",
    PageDataRoles : 'div[data-role="page"], div[data-role="dialog"]',
    OnTheMovePrefix : 'OnTheMove_'
    });

$(document).on('OnPreQuery', onTheMove.PageDataRoles, function (e, options) {
    var isChildAttachmentQueued = true;
    var knockoutContextName = options.knockoutContextName;
    if (TreeEnabled(knockoutContextName)) {
        var isModelReadyToAttachChildren = function () {
            var isReady = false;
            if (PageObj[knockoutContextName] != undefined) {
                isReady = (PageObj[knockoutContextName]().length > 0) && isChildAttachmentQueued;
            }

            return isReady;
        };
        var treeSettings = eval(knockoutContextName).Tree;
        treeSettings.knockoutContextName = knockoutContextName;
        $(onTheMove.PageDataRoles).on('OnTheMoveViewPreLoad', function (e, options) {
            if (isModelReadyToAttachChildren()) {
                getChildrenForMasterRecordList({
                    parentTable: eval(knockoutContextName).primaryTableName,
                    knockoutContextName: treeSettings.knockoutContextName,
                    parentIdColumn: treeSettings.ParentIdColumn,
                    masterIdColumn: treeSettings.MasterIdColumn
                });
                isChildAttachmentQueued = false;
            }
        });
    }
});
function getChildrenForMasterRecordList(options) {
    console.log('beep');
}

toHaveBeenCalledTimes(1)

now makes this much easier.

 expect(yourSpy).toHaveBeenCalledTimes(1);

Figured it out myself, spy has property callCount that auto-increments by one on each call.

    it("Invoking OnPreQuery will add event listener for OnTheMoveViewPreLoad event. Triggering OnTheMoveViewPreLoad twice will call getChildrenForMasterRecordList only first time", function () {
        AddTreeSettingsObjectToBC({ bc: bc, Tree: { IncludeChildren: true} });
        ComposeMockPageObjWithObservableFieldsWithChildren();
        var preQuerySpy = spyOnEvent(onTheMove.PageDataRoles, 'OnPreQuery');
        $(onTheMove.PageDataRoles).trigger('OnPreQuery', { knockoutContextName: 'bc' });
        expect('OnPreQuery').toHaveBeenTriggeredOn(onTheMove.PageDataRoles);
        expect(preQuerySpy).toHaveBeenTriggered();
        var getChildrenForMasterRecordListSpy = spyOn(window, 'getChildrenForMasterRecordList');
        $(onTheMove.PageDataRoles).trigger('OnTheMoveViewPreLoad', { knockoutContextName: 'bc' });
        expect(getChildrenForMasterRecordListSpy).toHaveBeenCalled();
        $(onTheMove.PageDataRoles).trigger('OnTheMoveViewPreLoad', { knockoutContextName: 'bc' });
        expect(getChildrenForMasterRecordListSpy.callCount).toEqual(1);
    });

as per comment

Read More:   AngularJS Directive element method binding - TypeError: Cannot use 'in' operator to search for 'functionName' in 1

in Jasmine 2.0 its

expect(object.func.calls.count()).toBe(1);


The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .

Similar Posts