1

i have a dummy Backbone.Model

App.Models.Note = Backbone.Model.extend({
      default: {
          title: ''
      }
);

and a Backbone.View for my model like the following:

  App.Views.NoteView = Backbone.View.extend({

    template: ...,

    initialize: function () {
        this.listenTo(this.model, "change", this.render);
        this.render();
    },

     render: function () {
        this.$el.html(this.template({
            title: this.model.get("title")
        }));
        return this;
     }
  });

For testing, i use mocha.js + chai + sinon, and i have the following test

 describe("App.Views.NoteView", function () {
      beforeEach(function () {
         this.view = new App.Views.NoteView({
              el: this.$fixture,
              model: new App.Models.Note()
        });
      }

      afterEach(function () {
          this.view.model.destroy();
      });

      it("my try 1", function () {
           var mySpy1 = sinon.spy(this.view, "render");

           this.view.model.set({
                 title: "a new Title"
           });

           expect(this.view.render).to.have.been.calledOnce;
       });
 }

What im trying to test is to spy the render method : when i change the model attributes the render method will be called. However, even if the render is executed normally, the test gives me error

'expected render to be called once but was called 0 times'

Any help?

user711189
  • 4,383
  • 4
  • 30
  • 48
  • sorry not sure i understand does it always give the error or only when you do not change a model attribute? – Quince Jul 17 '14 at 11:54
  • when changing the model's title, the render method is invoked normally. However the expectation produces the error above – user711189 Jul 17 '14 at 12:07
  • anyway, i found similar questions here: http://stackoverflow.com/questions/8441612/why-is-this-sinon-spy-not-being-called-when-i-run-this-test?rq=1 – user711189 Jul 17 '14 at 12:12

1 Answers1

0

Actually when the view is initialize it bind render function with it. So when we try to bind that render function with spy it does not allow. For that we have to bind spy before view initialization.

Try this:

  var mySpy1 = null;
  describe("App.Views.NoteView", function () {
  beforeEach(function () {
     mySpy1 = sinon.spy(App.Views.NoteView.prototype, "render");
     this.view = new App.Views.NoteView({
          el: this.$fixture,
          model: new App.Models.Note()
    });
  }

  afterEach(function () {
      this.view.model.destroy();
      //Restore
      App.Views.NoteView.prototype.render.restore();
  });

  it("my try 1", function () {
       this.view.model.set({
             title: "a new Title"
       });

       expect(mySpy1.called).to.be.true;
   });

}

Emmad Zahid
  • 438
  • 6
  • 15