65

I got the above error message when I ran my test. Below is my code (I'm using Backbone JS and Jasmine for testing). Does anyone know why this happens?

$(function() {
  describe("Category", function() {
     beforeEach(function() {
      category = new Category;
      sinon.spy(jQuery, "ajax");
     }

     it("should fetch notes", function() {
      category.set({code: 123});
      category.fetchNotes();
      expect(category.trigger).toHaveBeenCalled();
     }
  })
}
trivektor
  • 5,608
  • 9
  • 37
  • 53

2 Answers2

99

You have to remove the spy after every test. Take a look at the example from the sinon docs:

{
    setUp: function () {
        sinon.spy(jQuery, "ajax");
    },

    tearDown: function () {
        jQuery.ajax.restore(); // Unwraps the spy
    },

    "test should inspect jQuery.getJSON's usage of jQuery.ajax": function () {
        jQuery.getJSON("/some/resource");

        assert(jQuery.ajax.calledOnce);
        assertEquals("/some/resource", jQuery.ajax.getCall(0).args[0].url);
        assertEquals("json", jQuery.ajax.getCall(0).args[0].dataType);
    }
}

So in your jasmine test should look like this:

$(function() {
  describe("Category", function() {
     beforeEach(function() {
      category = new Category;
      sinon.spy(jQuery, "ajax");
     }

     afterEach(function () {
        jQuery.ajax.restore();
     });

     it("should fetch notes", function() {
      category.set({code: 123});
      category.fetchNotes();
      expect(category.trigger).toHaveBeenCalled();
     }
  })
}
Andreas Köberle
  • 106,652
  • 57
  • 273
  • 297
  • In one of my trials, I had an afterEach block too but it didn't solve the problem. Could it be because I put the afterEeach after all the tests instead of right after beforeEach? – trivektor Jan 11 '12 at 20:26
  • I think so, cause `beforeEach`and `afterEach` are function calls just as your tests. So calling `afterEach` after all your tests will have no effect. – Andreas Köberle Jan 11 '12 at 20:30
  • process.exit.restore(); ... nice – danday74 Apr 06 '17 at 04:07
  • 2019...Juste add into describe block this function : afterEach(function () { jQuery.ajax.restore(); }); or afterEach(function () { $.ajax.restore(); }); It depend your import about jQuery. often we writed "import * as $ from ..." – Vifier Lockla Aug 22 '19 at 20:05
  • Was still facing this issue, thanks to my colleague who left this hole in his test cases. worked after closing it. – Tukaram Bhosale Mar 10 '21 at 22:00
9

What you need in the very beginning is:

  before ->
    sandbox = sinon.sandbox.create()

  afterEach ->
    sandbox.restore()

Then call something like:

windowSpy = sandbox.spy windowService, 'scroll'
  • Please notice that I use coffee script.
Winters Huang
  • 761
  • 10
  • 18