jasmine: spyOn(obj, 'method').andCallFake or and.callFake?

85,955

Yes, the spy API changed from Jasmine 1.3.1 to Jasmine 2.0. There's no "correct" version. If you can find the tool support for Jasmine 2.0, I would recommend upgrading.

Jasmine 1.3.1 syntax (documentation [archived link])

spyOn(mBankAccountResource, 'getBankAccountData').andCallFake(fakedFunction);
expect(mBankAccountResource.getBankAccountData.mostRecentCall.args).toEqual(["foo"]);

Jasmine 2.0 syntax (documentation [archived link])

// Methods moved to 'and' property
spyOn(mBankAccountResource, 'getBankAccountData').and.callFake(fakedFunction);

// Call data moved to 'calls' property
expect(mBankAccountResource.getBankAccountData.calls.mostRecent().args).toEqual(["foo"]);

I mention tool support because it seems that's the problem you're having. Jasmine 2.0 has only been out for a couple of months (at the time of writing). Support for Jasmine 2.0 in Karma, by comparison, has been out for a couple of weeks (I'm not sure about other tools).

To solve your issue, investigate which tool(s) you're using to run tests and see if any of them support Jasmine 2.0. If all of them do, then go for the upgrade. Otherwise, downgrade your browser tests to Jasmine 1.3.1 and wait until tool support is better. Just make sure you're consistent across the board.

Share:
85,955
Philipp Claßen
Author by

Philipp Claßen

Member of the Ghostery engineering team.

Updated on August 23, 2022

Comments

  • Philipp Claßen
    Philipp Claßen almost 2 years

    I want to mock test data in my Jasmine tests. Here are two versions:

    // version 1:
    spyOn(mBankAccountResource, 'getBankAccountData').and.callFake(fakedFunction);
    
    // version 2:
    spyOn(mBankAccountResource, 'getBankAccountData').andCallFake(fakedFunction);
    

    When I execute my tests with a browser (Chrome, Firefox) then the first version works. However, when I run the same test with phantomjs, I have to use the second version. Otherwise, it complains that the function is not defined.

    Here are the error messages:

    // phantomjs (with version 1)
        TypeError: 'undefined' is not an object (evaluating 'spyOn(mBankAccountResource, 'getBankAccountData').and.callFake')
        at /home/phil/workspaces/world/basket.angular.ui/basket.angular.ui/test/bankaccount/BankAccountCtrlTest.js:65
        at invoke (/home/phil/workspaces/world/basket.angular.ui/bower_components/angular/angular.js:3707)
        at workFn (/home/phil/workspaces/world/basket.angular.ui/bower_components/angular-mocks/angular-mocks.js:2149)
    undefined
    
    // Chrome (with version 2)
    TypeError: Object function () {
            callTracker.track({
              object: this,
              args: Array.prototype.slice.apply(arguments)
            });
            return spyStrategy.exec.apply(this, arguments);
          } has no method 'andCallFake'
        at Object.<anonymous> (/home/phil/workspaces/world/basket.angular.ui/basket.angular.ui/test/bankaccount/BankAccountCtrlTest.js:65:59)
        at Object.invoke (/home/phil/workspaces/world/basket.angular.ui/bower_components/angular/angular.js:3707:17)
        at Object.workFn (/home/phil/workspaces/world/basket.angular.ui/bower_components/angular-mocks/angular-mocks.js:2149:20)
    

    I searched the Jasmine API but could not find out which version is the correct one. All examples that I found seem to use the second version.

    Did the API of Jasmine change recently? How can I write my tests, so it always works?

  • Philipp Claßen
    Philipp Claßen over 10 years
    Thanks! My global installation of karma-jasmine was 2.0, but some projects used karma-jasmine 1.3 locally. Depending on how I executed my tests, either the 2.0 or the 1.3 version was used.