2013-01-14 4 views
8

Używam funkcji do pobierania danych z webapi. Zasadniczo przy użyciu $.ajax.Jak używać jaśminu do testowania funkcji asynchronicznej, która wymaga długiego czasu reakcji?

Jestem teraz sprawdzając je za pomocą waits() tak:

describe('xxxxxxxxxxxxxxxxxxxxx', function() { 
    var r; 
    it('fetchFilter', function() { 
    runs(function() { 
     model.fetch(opts) 
     .done(function(data) { 
     r = data; 
     }); 
    }); 

    waits(2000); 

    runs(function() { 
     expect(r[0].gender).toBeDefined(); 
    }); 
    }); 
}); 

Problemem jest:

  1. To nie jest zagwarantowane, że waits(2000) będzie wykonać zadanie dobrze. Z różnych powodów (połączenia sieciowe, wydajność algorytmu api to ja, itp.), Mogę potrzebować do waits(5000) lub więcej, lub dla niektórych modeli wystarczy waits(500). Najbardziej denerwujące jest to, że wszystko wymyka się spod kontroli.
  2. Wiele z waits() powoduje, że test-specyfikacje-przebiegi tracą dużo czasu na oczekiwanie. Czas uruchomienia całego zestawu jest zbyt długi, aby go zaakceptować.

Czy jest jakiś best practice robienia takich rzeczy?

PS: Wiem, że test jednostkowy nie powinien być stosowany do niektórych funkcji opartych na webapi lub bazie danych. Ale pracuję z pojedynczą stroną - js-heavy-webapp. Proces pobierania danych jest tak samo ważny jak to, w jaki sposób będę je wykorzystywać za pomocą modeli js.

Odpowiedz

11

waitsFor() będzie czekać przez określony zatrzasku zwrotnego powrót true (będzie próbować wiele czasu co kilka ms). Podniesie także wyjątek, jeśli przekroczony zostanie określony czas oczekiwania (w tym przypadku 5000 ms).

describe('xxxxxxxxxxxxxxxxxxxxx', function() { 
    var r, fetchDone; 

    it('fetchFilter', function() { 

    runs(function() { 
     model.fetch(opts).done(function(data) { 
     r = data; 
     fetchDone = true; 
     }); 
    }); 

    waitsFor(function() { 
     return fetchDone; 
    }, 5000); 

    runs(function() { 
     expect(r[0].gender).toBeDefined(); 
    }); 

    }); 
}); 

sprawdzić Jasmine docs uzyskać więcej informacji na waitsFor() i runs()

+0

Kiedy będzie "Komunikat błędu" pokazać? Limit czasu wyświetla własny komunikat o błędzie. – hbrls

+0

Jeśli nie określisz komunikatu o błędzie, wyświetli się domyślny komunikat o przekroczeniu limitu czasu. Jeśli potrzebujesz niestandardowej wiadomości, możesz użyć 'waitFor (function() {return fetchDone;}," Przekroczono czas oczekiwania na pobranie, itd., Itp. ", 5000);' – istepaniuk

+6

'waitFor' jest niedostępne w jaśminie2. – Gurpreet

2

Poniższe rozwiązanie pozwala poczekać nie więcej niż naprawdę konieczne, ale wciąż trzeba zdefiniować maksymalny czas oczekiwania, który powinien być wystarczający. Funkcja waitsFor przejmuje funkcję i czeka, aż zwróci ona true lub upłynął limit czasu, gdy wygasł ostatni argument. W przeciwnym razie nie powiedzie się.

Przypuśćmy rzeczy trzeba czekać na to, że r[0] jest zdefiniowana w ogóle, może to być:

waitsFor(
    function() { return r[0]; }, 
    'the data should be already set', 
    5000); 
-1

zgodnie jasmine 2.5, można przekazać dodatkowe paramater dla it("scenario", callback, timeout)

describe('xxxxxxxxxxxxxxxxxxxxx', function (done) { 
    var r, fetchDone; 

    it('fetchFilter', function() { 

    runs(function() { 
     model.fetch(opts).done(function(data) { 
     r = data; 
     fetchDone = true; 
     }); 
    }); 

    setTimeout(function() { 
     done(); 
    }, 9000); 

    runs(function() { 
     expect(r[0].gender).toBeDefined(); 
    }); 

    }); 
},10000);