2012-05-10 72 views
20

我試圖用Jasmine寫一些測試,但現在有一個問題,如果有一些代碼是異步的在beforeEach如何測試Jasmine中的方法,如果beforeEach中的代碼是異步的?

示例代碼看起來像:

describe("Jasmine", function() { 

    var data ; 

    beforeEach(function(){ 
     console.log('Before each'); 
     getSomeDataFromRemote(function(res){ 
      data = res; 
     }); 
    }); 

    it("test1", function() { 
     expect(data).toBe(something); 
     console.log('Test finished'); 
    }); 

}); 

可以看到,在beforeEach,我想從遠程獲取一些數據,並將其分配給data異步。

但在test1,當我嘗試驗證:

expect(data).toBe(something); 

的數據是undefined,因爲getSomeDataFromRemote尚未完成。

如何解決?

+0

我知道摩卡可以做異步設置,但我不太熟悉茉莉花。你有沒有嘗試在你的'beforeEach'中使用[異步規範結構](https://github.com/pivotal/jasmine/wiki/Asynchronous-specs)?文檔只顯示它們在規範中使用,但它們也可能在'beforeEach'中運行。 –

回答

23

就像一個it內異步的東西,你可以使用runswaitsFor在beforeEach:

define('Jasmine' , function() { 
    var data ; 

    beforeEach(function(){ 
     runs(function() { 
      getSomeDataFromRemote(function(res){ 
       data = res; 
      }); 
     }); 

     waitsFor(function() { return !!data; } , 'Timed out', 1000); 
    }); 

    it("test1", function() { 
     runs(function() { 
       expect(data).toBe(something); 
     }); 
    }); 
}); 

雖然我會認爲,那是因爲這是測試代碼,我認爲你應該有在getSomeDataFromRemote打電話給你it因爲這裏面實際上你在測試什麼;)

你可以看到在一些測試中,我已經爲異步API這裏寫了一些大規模的例子:https://github.com/aaronpowell/db.js/blob/f8a1c331a20e14e286e3f21ff8cea8c2e3e57be6/tests/public/specs/open-db.js

+2

等待已經停止在Jasmine中運行。現在,您可以使用done()。希望這有助於 - http://jasmine.github.io/2.0/introduction.html#section-Asynchronous_Support –

3

在這種情況下,我通常會存儲異步調用以立即響應。

我不確定你是否看過它,但​​是關於與Jasmine進行異步測試的一些文檔。

+0

我剛剛檢查了你的鏈接,但仍然不知道如何在我的情況下做到這一點。 – Freewind

+0

您可以將'getSomeDataFromRemote'調用包裝在'runs'函數中,以及期望。您可以使用'waits'來提供一段足夠長的時間,然後再運行您的期望。確實很費勁,並且可能導致隨機失敗。這就是爲什麼我只是存根電話立即返回。 [Sinon.js](http://sinonjs.org/)在ajax存根區域也提供了一些幫助,如果你更喜歡金屬之外的東西。 – x1a4

+0

謝謝,'runs'和'waitsFor'正是我正在尋找的。但是,@Slace給了我一個工作和細節的例子,我不得不接受他的回答。對不起〜 – Freewind

15

Jasmine 2.0

要小心,因爲在新的茉莉花2.0,這是不會改變,這將是摩卡風格。您必須使用done()函數beforeEach()it()。例如,假設您想在LAMP服務器中使用jQuery $.get來測試頁面是否存在並且不是空的。首先,你需要的jQuery添加到SpecRunner.html文件,並在文件spec.js

describe('The "index.php" should', function() { 
    var pageStatus; 
    var contents; 

    beforeEach(function (done) { 
     $.get('views/index.php', function (data, status) { 
      contents = data; 
      pageStatus = status; 
      done(); 
     }).fail(function (object, status) { 
      pageStatus = status; 
      done(); 
     }); 
    }); 

    it('exist', function(done) { 
     expect(status).toBe('success'); 
     done(); 
    }); 

    it('have content', function(done) { 
     expect(contents).not.toBe(''); 
     expect(contents).not.toBe(undefined); 
     done(); 
    }); 
}); 

正如你所看到的,你傳遞給函數done()beforeEach()it()參數。當您運行測試時,it()將不會啓動,直到在beforeEach()函數中調用done()爲止,所以在獲得服務器的響應之前,您不會啓動期望。

的頁面存在

如果頁面存在,我們捕獲狀態,並從服務器的響應數據,我們稱之爲done()。然後我們檢查狀態是否爲「成功」,以及數據是否爲空或未定義。

的頁面不存在

如果該頁面不存在,我們捕獲來自服務器的響應的狀態,我們稱之爲done()。然後我們檢查狀態是不是「成功」,以及數據是空的還是未定義的(這一定是因爲文件不存在)。

+0

'done()'也適用於[minijasminenode](https://github.com/juliemr/minijasminenode) –

+0

等項目,我發現beforeAll不支持異步樣式。下面的規範將在beforeAll調用之前運行「完成「 – Kaicui

+2

爲什麼將'''''''傳遞給''''''''''函數並調用?如果它們從'''it'''中被省略了會出什麼問題? – paulhhowells

相關問題