Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 专注相关行为的摩卡测试(主干/咖啡脚本应用程序)_Javascript_Jquery_Backbone.js_Coffeescript_Mocha.js - Fatal编程技术网

Javascript 专注相关行为的摩卡测试(主干/咖啡脚本应用程序)

Javascript 专注相关行为的摩卡测试(主干/咖啡脚本应用程序),javascript,jquery,backbone.js,coffeescript,mocha.js,Javascript,Jquery,Backbone.js,Coffeescript,Mocha.js,我有一个用咖啡脚本编写的主干应用程序。我正试图使用Mocha(与Chai和Sinon一起)编写DOM相关行为的测试,但似乎隐藏的fixture(我现在正在使用,但我也用一个隐藏的“#fixtures”div)没有注册特定的DOM相关行为,这使得测试特定类型的DOM相关行为(似乎是不成功的)不可能 例如,我的主应用程序视图有几个从未同时渲染的子视图:当应用程序视图渲染子视图A时,它会记住当前活动子视图B的聚焦元素(@_visibleView),保存子视图B上的信息,关闭子视图B,然后渲染子视图A

我有一个用咖啡脚本编写的主干应用程序。我正试图使用Mocha(与Chai和Sinon一起)编写DOM相关行为的测试,但似乎隐藏的fixture(我现在正在使用,但我也用一个隐藏的
“#fixtures”
div)没有注册特定的DOM相关行为,这使得测试特定类型的DOM相关行为(似乎是不成功的)不可能

例如,我的主应用程序视图有几个从未同时渲染的子视图:当应用程序视图渲染子视图A时,它会记住当前活动子视图B的聚焦元素(
@_visibleView
),保存子视图B上的信息,关闭子视图B,然后渲染子视图A

    _rememberFocusedElement: ->
      focusedElement = $ document.activeElement
      if focusedElement
        focusedElementId = focusedElement.attr 'id'
        if focusedElementId
          @_visibleView?.focusedElementId = focusedElementId
当我手动测试它时,这是可行的,但当我尝试为此行为编写单元测试时,它们失败了,因为我无法将焦点(例如,通过
$(选择器).focus()
)设置到隐藏div/iframe中的元素。(我对监听窗口大小调整事件的功能也有同样的问题。)

我认为如果我将
$document.activeElement
更改为
@$':focus“
可能会得到不同的结果,但这并不能解决问题

以下是我的摩卡(BDD)测试的相关部分。此规范将打印
TEXTAREA
到控制台,然后打印
undefined
,表示有一个id='transcription'的TEXTAREA,但我无法将焦点设置为它

    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'
每次之前(完成)->
fixtures.path='fixtures'
回调==>
@$fixture=fixtures.window()。$“”
@appView=新appView el:@$fixture
完成()
描述“图形用户界面的东西”,->
它“记住子视图中当前聚焦的元素”(完成)->
@appView.mainMenuView.once“请求:格式添加”,=>
@appView._visibleView.$(“#转录”).focus()
console.log@appView._visibleView.$(“#转录”).prop“标记名”
console.log@appView._visibleView.$(':focus').prop“标记名”
完成()
@appView.mainMenuView.trigger'请求: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

当然,现在你可能会想:“很好,这在测试领域对我很有帮助,但我怎么知道它在真实环境中会起作用呢?”我的答案是,你的(可能是基于硒的)验收测试应该涵盖这类内容。验收测试应该检查您的整个代码是否在真实世界中工作,而单元测试应该确保该代码的各个部分在虚假环境中工作

前者非常有助于确保您的客户不会看到bug,而后者非常有助于准确地找出这些bug的来源,并使您能够安全地进行重构