2012-10-30 9 views
55

Mam dość prostą funkcję, która zwraca .ajax jQuery() obietnicę jako takie:Jak prawidłowo testować jQuery. Ajax() jQuery obiecuje używając Jasmine i/lub Sinon?

CLAW.controls.validateLocation = function(val, $inputEl) { 
    return $.ajax({ 
     url: locationServiceUrl + 'ValidateLocation/', 
     data: { 
      'locationName': val 
     }, 
     beforeSend: function() { 
      $inputEl.addClass('busy'); 
     } 
    }).done(function(result) { 
     // some success clauses 
    }).fail(function(result) { 
     // some failure clauses 
    }).always(function() { 
     // some always clauses 
    }); 
} 

w przeważającej części, to nowy interfejs obietnice działa jak sen, a eliminując piramidy zwrotnych przy użyciu jQuery .ajax() jest świetny. Jednak nie mogę dla życia mnie dowiedzieć się, jak prawidłowo przetestować te obietnice pomocą jaśminu i/lub sinon:

  1. Cała dokumentacja sinon zakłada używasz starej szkoły wywołań zwrotnych; Nie widzę jeden przykład tego, jak go używać z obietnic/deferreds

  2. Gdy próbuje użyć Jasmine lub sinon szpieg szpiegowanie $ .ajax The szpieg jest skutecznie nadpisywania obietnicę, więc jej done, fail, i always klauzule nie istnieją już od funkcji ajax, więc obietnica nigdy nie rozwiązuje i rzuca błąd zamiast

bym naprawdę kochać przykład lub dwa jak przetestować te nowe jQuery .ajax() obiecuje z wyżej wymienionymi testowymi bibliotekami. Przeszukałem sieć dość intensywnie i tak naprawdę nie doszedłem do niczego. Jeden zasób, który znalazłem wspomniał, używając Jasmine.ajax, ale chciałbym tego uniknąć, jeśli to możliwe, ponieważ Sinon zapewnia większość tych samych funkcji po wyjęciu z pudełka.

Odpowiedz

105

To nie jest tak skomplikowane. Wystarczy, że zwrócisz obietnicę i rozwiążesz ją zgodnie ze swoim przypadkiem.

Na przykład:

spyOn($, 'ajax').andCallFake(function (req) { 
    var d = $.Deferred(); 
    d.resolve(data_you_expect); 
    return d.promise(); 
}); 

o sukcesie lub

spyOn($, 'ajax').andCallFake(function (req) { 
    var d = $.Deferred(); 
    d.reject(fail_result); 
    return d.promise(); 
}); 

na niepowodzenie.

Dla Jasmine 2.0 składnia zmieniła się nieznacznie:

spyOn($, 'ajax').and.callFake(function (req) {}); 

metoda .andCallFake() nie istnieje w Jasmine 2,0

+0

To działało wspaniale; wielkie dzięki! –

+0

Nie ma problemu, przyjemność;) – ggozad

+8

Wszelkie pomysły na sposób Sinon? – lucke84

16

coś wzdłuż tych linii/z Sinon i jQuery deferreds

ajaxStub = sinon.stub($, "ajax"); 

function okResponse() { 
    var d = $.Deferred(); 
    d.resolve({ username: "testuser", userid: "userid", success: true }); 
    return d.promise(); 
}; 

function errorResponse() { 
var d = $.Deferred(); 
d.reject({},{},"could not complete"); 
return d.promise(); 
}; 

ajaxStub.returns(okResponse()); 
ajaxStub.returns(errorResponse()); 
+0

Zapomniałeś o wywołaniach 'success' i' error'. – Vanuan

0

Oto prostsze podejście z tylko javascript.

quoteSnapshots: function (symbol, streamId) { 
       var FakeDeferred = function() { 
        this.error = function (fn) { 
         if (symbol.toLowerCase() === 'bad-symbol') { 
          fn({Error: 'test'}); 
         } 
         return this; 
        }; 
        this.data = function (fn) { 
         if (symbol.toLowerCase() !== 'bad-symbol') { 
          fn({}); 
         } 
         return this; 
        }; 
       }; 

       return new FakeDeferred(); 
      } 

if instrukcje wewnątrz każdego zwrotnego są co używam w moim teście jazdy sukces lub wykonanie błędzie.

0

Rozwiązanie podane przez @ggozad nie zadziała, jeśli użyjesz rzeczy takich jak .complete().

Ale, hura, jaśmin wykonane wtyczki dokładnie to zrobić: http://jasmine.github.io/2.0/ajax.html

beforeEach(function() { 
    jasmine.Ajax.install(); 
}); 

afterEach(function() { 
    jasmine.Ajax.uninstall(); 
}); 

//in your tests 
expect(jasmine.Ajax.requests.mostRecent().url).toBe('/some/cool/url');