2013-05-05 10 views

Odpowiedz

1

Możesz użyć Sinon.js do stworzenia fałszywego serwera do testów.

http://sinonjs.org/

Przykładowy kod:

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

Trzeba sinon naśladować odpowiedzi serwera. Biblioteka ta zawiera narzędzia tak:

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

Więc gdy masz model z odcinka i id 123 root sinon wróci to na wezwanie pobierania.

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

Aktualizacja: Dodanie drugiego obejścia jako wniosek pytającego. Metoda zapisywania.

// Użyj tego w badaniach zamiast backbone.js Modelu

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({ 
}); 

Jednak nadal jestem Proponuję użyć sinon. Prześmiewanie się z Backbone.js nie jest eleganckie, a także obsługuje kody odpowiedzi w nagłówku, a inne rzeczy są również bardziej skomplikowane i stanowią rodzaj odkrywczego koła. Podczas gdy z sinonem wystarczy dodać bibliotekę, utwórz odpowiedź serwera.

+0

Używam następujące technologie: backbone.js, require.js, jquery, Rest services przez WebAPI. z jaśminu kpię z obiektu modelu i wiążę go z widokiem do testowania jednostkowego. kiedy otrzymam odpowiedź z widoku na model próbny, jak jednostronnie zareagować na zachowanie (sukces, błąd) modelu. nie ma sposobu, aby przetestować modele odpowiedzi bez grzechu. – Gururaj

+0

Sinon jest po prostu inną biblioteką JavaScript, nie wiem, dlaczego nie możesz go dodać. W każdym razie, inne obejście polega na zastąpieniu metody zapisu. Dodam to obejście w mojej odpowiedzi. –

2

Aby przetestować to bez fałszywego serwera, można przetestować, czy funkcja została powiązana z modelem, a następnie wywołać samodzielnie funkcję binded. Innymi słowy wyśmiewać ajax zapisać część z modelu.

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

Nie jestem pewien, Lubię chodzić przez Sinon tu przecież wywołanie ajax jest przez kręgosłup, a nie przez jednostki testowanej, tu jest moje rozwiązanie

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(); 
    }); 
Powiązane problemy