簡體   English   中英

Mocha測試與焦點相關的行為(Backbone / CoffeeScript應用程序)

[英]Mocha tests on focus-related behaviors (Backbone/CoffeeScript app)

我有一個用CoffeeScript編寫的Backbone應用程序。 我正在嘗試使用Mocha(與Chai和Sinon一起)為DOM相關行為編寫測試,但似乎是隱藏的燈具(我現在正在使用js-fixture,但我也試過這個沒有成功的隱藏'#fixtures' )沒有注冊某些與DOM相關的行為,這使得測試某些類型的DOM相關行為(看似)是不可能的。

例如,我的主應用程序視圖有幾個從不同時呈現的子視圖:當應用程序視圖呈現子視圖A時,它會記住當前活動子視圖B( @_visibleView )的焦點元素,將該信息保存在子視圖B上,關閉子視圖B,然后渲染子視圖A.

    _rememberFocusedElement: ->
      focusedElement = $ document.activeElement
      if focusedElement
        focusedElementId = focusedElement.attr 'id'
        if focusedElementId
          @_visibleView?.focusedElementId = focusedElementId

這在我手動測試時有效,但當我嘗試為此行為編寫單元測試時,它們會失敗,因為我無法將焦點(例如,通過$(selector).focus() )設置為隱藏div / iframe中的元素。 (我在監聽窗口大小調整事件的功能方面遇到了同樣的問題。)

我認為如果我將$ document.activeElement更改$ document.activeElement @$ ':focus"我可能會得到不同的結果,但這並不能解決問題。

以下是我的Mocha(BDD)測試的相關部分。 該規范將打印TEXTAREA到控制台,然后undefined ,表明有一個 id =“轉錄”一個文本,但我不能將焦點設置到它。

    beforeEach (done) ->
      fixtures.path = 'fixtures'
      callback = =>
        @$fixture = fixtures.window().$ "<div id='js-fixtures-fixture'></div>"
        @appView = new AppView el: @$fixture
        done()

    describe 'GUI stuff', ->
      it 'remembers the currently focused element of a subview', (done) ->
        @appView.mainMenuView.once 'request:formAdd', =>
          @appView._visibleView.$('#transcription').focus()
          console.log @appView._visibleView.$('#transcription').prop 'tagName'
          console.log @appView._visibleView.$(':focus').prop 'tagName'
          done()
        @appView.mainMenuView.trigger 'request:formAdd'

有什么方法可以為這些類型的行為編寫單元測試嗎?

好的,首先讓我澄清一下:“單元測試”一詞對很多人來說意味着不同的東西。 它經常成為“使用單元測試框架(如Mocha)編寫的任何測試的同義詞”。 當我使用術語“單元測試”時,這不是我的意思:我的意思是測試只測試單個工作單元(在JS環境中,通常是單個函數,但可能是整個類)。

好的,如果你真的試圖對你的代碼進行單元測試,你就會采取錯誤的方法。 單元測試實際上不應該依賴於被測試函數的上下文之外的任何東西,因此依賴於(外部)DOM就是問題所在。

讓我們假設您的焦點處理代碼位於一個名為handleFocus的函數中(我不知道實際的方法名稱)。 考慮以下測試,我將使用JavaScript編寫,因為我的CoffeScript是生銹的:

describe('#handleFocus', function() {
    it('remembers the currently focused element of a subview', function() {
        var setFocusStub = sinon.stub($.fn, 'focus');
        appView._visibleView.handleFocus();
        expect(setFocusStub.calledOnce).to.be(true);
    });
});

以上是一個過度簡化,但希望它說明了這一點。 你真正想要檢查的不是DOM(假的還是真的)是否做X; 您正在嘗試檢查的是您的函數是否執行X.通過關注測試中的那個,並依賴於檢查“X”是否發生的存根,您完全消除了涉及DOM的需要。

當然,你可能會想:“非常好,這有助於我在試驗場,但我怎么知道它會在真實環境中起作用?” 我的答案是你的(可能是基於Selenium的) 驗收測試應該涵蓋那種事情。 驗收測試應檢查您的整體代碼是否在現實世界中工作,而單元測試應確保該代碼的各個部分在虛假環境中工作。

前者非常適合確保您的客戶不會看到錯誤,而后者非常適合確定錯誤的來源,並使您能夠安全地進行重構。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM