2013-05-05 14 views
5
onSaveEvent: function (event) { 
       if (this.model !== null) { 
        var that = this; 

        this.model.save(this.model.toJSON(), { 
         success: function (model) { 
          that.model = model; 
          that.model.attributes.isDirty = false; 
         }, 

         error: function (model, xhr) { 
          that.model.attributes.isDirty = true; 
         } 
        }); 
       } 
      } 
     } 

come testare l'unità del successo di salvataggio del modello e le risposte di errore in Jasmine?come testare il successo della dorsale e la risposta all'errore su save usando gelsomino

risposta

1

È possibile utilizzare Sinon.js per creare un server falso per i test.

http://sinonjs.org/

codice Esempio:

describe("when saving a user model", function() { 

    beforeEach(function() { 
     this.server = sinon.fakeServer.create(); 
     this.responseBody = '{"name":"test user","id":1,"title":"tester"}'; 
     this.server.respondWith(
     "POST", 
     "/user", 
     [ 
      200, 
      {"Content-Type": "application/json"}, 
      this.responseBody 
     ] 
    ); 
     this.eventSpy = sinon.spy(); 
    }); 

    afterEach(function() { 
     this.server.restore(); 
    }); 

    it("should not save when name is blank", function() { 
     this.user.bind("error", this.eventSpy); 
     this.user.save({"name": ""}); 

     expect(this.eventSpy).toHaveBeenCalledOnce();  
     expect(this.eventSpy).toHaveBeenCalledWith(this.user, "cannot have a blank name"); 
    }); 

    it("should call the server", function() { 
     this.user.save(); 
     expect(this.server.requests[0].method).toEqual("POST"); 
     expect(this.server.requests[0].url).toEqual("/user"); 
     expect(JSON.parse(this.server.requests[0].requestBody)).toEqual(this.user.attributes); 
    }); 

    }); 
0

devi Sinon di emulare le risposte del server. Questa libreria ha utilità come questo:

this.server.respondWith("GET", "/episode/123", 
     [200, {"Content-Type": "application/json"}, 
     '{"id":123,"title":"Hollywood - Part 2"}']); 

Così ogni volta che si dispone di un modello con l'episodio della radice e l'ID 123, Sinon tornerà questo su una chiamata di recupero.

Leggi questo: http://tinnedfruit.com/2011/03/03/testing-backbone-apps-with-jasmine-sinon.html

Aggiornamento: L'aggiunta di una seconda soluzione come richiesta richiedente. Metodo di salvataggio mocking.

// Utilizzare questo nei test invece di Backbone.js Modello

var ExtendedModel = Backbone.Model.extend({ 
    //mocked save: 
    save : function(data, options){ 
     if(data){ 
      this.set(data); 
     } 
     var mocked = this.toJSON(); 
     if(!mocked.id){ 
      mocked.id = new Date().getTime(); 
     } 
     mocked = this.parse(mocked); 
     if(options.success){ 
      options.success(this); 
     } 
     if(options.error){ 
      options.error(this); 
     } 
    } 
}); 

var MyModel = ExtendedModel.extend({ 
}); 

Tuttavia io sono ancora suggerisco di utilizzare Sinon. Mocking the Backbone.js non è ellegante e supporta anche i codici di risposta dell'header e altre cose sono anche più complesse e una sorta di reinventare la ruota. Mentre con sinon hai solo bisogno di aggiungere la libreria e creare una risposta al server.

+0

Sto usando la le seguenti tecnologie: backbone.js, require.js, jquery, servizi di Rest su WebAPI. dal gelsomino, sto prendendo in giro l'oggetto del modello e mi lego a una vista per il test delle unità. quando ottengo la risposta dalla vista al modello di simulazione, come unire le risposte di salvataggio (di successo, di errore) del modello. non c'è un modo per testare unitamente le risposte del modello senza sinon. – Gururaj

+0

Sinon è solo un'altra lib JavaScript, non è sicuro del perché non è possibile aggiungerlo. Ma in ogni caso, un'altra soluzione è sovrascrivere il metodo di salvataggio. Aggiungerò questa soluzione alla mia risposta. –

2

Per verificare ciò senza un server falso, è possibile verificare che la funzione sia stata associata al modello e quindi chiamare da sé la funzione associata. In altre parole, prendi in giro la parte salva ajax dal modello.

var view = new YourView() 
jasmine.spyOne(view.model, 'save') 
view. onSaveEvent() 
var args = view.model.save.mostRecentCall.args 

args[1].success() 
expect(view.model.attributes.isDirty).toBeFalsy() 

args[1].error() 
expect(view.model.attributes.isDirty). toBeTruthy() 
0

io non sono sicuro di come passare attraverso Sinon qui, dopotutto la chiamata AJAX è fatto da spina dorsale, non per l'unità che si sta testando, ecco la mia soluzione

var Model = Backbone.Model.extend({ 
     success_callback : function (model){ 
     this.model = model; 
     this.model.attributes.isDirty = false; 

     }, 
     error_callback: function (model, xhr){ 

     }, 
     onSaveEvent: function (event) { 

     this.save([], { 
      success: _.bind(this.save_success, this), 
      error: _.bind(this.error_callback, this); 
     }); 
    }); 


    var callback_invoker = function(type_str, which_argument) { 
     this.which_argument = which_argument || 0; 
     this.type_str = type_str; 
     var func = function() { 
     var options = arguments[this.which_argument] || {}; 
     if (this.type_str == 'success') { 
      var run = options.success || function() {}; 

     }else if (this.type_str == 'error') { 
      var run = options.error || function() {}; 
     } 
     run(); 
     }; 
     this.function = _.bind(func, this); 
    }; 

    it('save success calls callback', function() { 
     instance = new Model(); 
     spyOn(instance, 'save_success'); 
     spyOn(_,'bind').andCallThrough(); 
     var invoker = new callback_invoker('success', 1); 
     spyOn(instance, 'save').andCallFake(invoker.function); 
     instance.onSaveEvent(); 
     expect(_.bind).toHaveBeenCalledWith(instance.save_success, instance); 
     expect(instance.save_success).toHaveBeenCalled(); 
    }); 
Problemi correlati