【问题标题】:Jasmine shared specs scoping issues with coffeescriptJasmine 与咖啡脚本共享规范范围问题
【发布时间】:2013-02-16 04:50:30
【问题描述】:

我试图通过提取共享示例来干掉一些茉莉花测试。

@sharedExamplesForThing = (thing) ->
  beforeEach ->
    @thingy = new thing

  it "is neat", ->
    expect(@thingy.neat).toBeTruthy()


describe "widget with shared behavior", ->
  sharedExamplesForThing(-> new Widget)

当所有内容都定义在一个文件中时,这很有效。当我尝试将 sharedExamples 移动到单独的文件时,会出现我遇到的问题。我得到Can't find variable: sharedExamplesForThing ...

所以为了调试,我尝试了以下方法:

describe "widget with shared behavior", ->
  it "is acting like a meany", ->
    console.log sharedExamplesForThing
    expect(false).toBeTruthy()
  sharedExamplesForThing(-> new Widget)

is acting like a meany 块中,日志将sharedExamplesForThing 显示为[Function],但我仍然在it 之外得到Can't find variable。我觉得这可能与我当前经验之外的范围界定问题有关,但我可能完全错了。我在这里错过了什么?

(使用 rails、jasminerice、guard-jasmine)

【问题讨论】:

    标签: javascript coffeescript tdd jasmine


    【解决方案1】:

    当您在 CoffeeScript 中分配顶级成员变量时,它被分配为全局对象的属性(浏览器中的window)。因此它会生成以下 JavaScript:

    window.sharedExamplesForThing = ...;
    

    这意味着您可以在文件外部将其称为window.sharedExamplesForThing 或只是sharedExamplesForThing。因此,假设已在规范文件之前加载了共享示例文件,那么您所做的应该可以工作。我认为您遇到的问题是首先加载了规范文件(因为在加载文件时运行描述函数,而在加载所有文件后运行函数)。因此,您可能需要调整加载顺序,您可以尝试将共享示例文件放在 support 目录中,然后首先要求这样做。

    与其将变量直接分配给窗口对象,不如设置一个命名空间来将您的共享变量导出到其中(这样您就不会弄乱全局对象):

    window.MyNamespace = {}
    
    MyNamespace.sharedExamplesForThing = ...
    

    然后在您的规范文件中,您可以将其称为MyNamespace.sharedExamplesForThing

    我发现查看生成的 JavaScript 有助于了解 CoffeeScript 如何在文件之间导出变量。

    【讨论】:

      【解决方案2】:

      这是我写的关于如何最好地共享示例的博客文章。希望这会有所帮助。

      http://pivotallabs.com/drying-up-jasmine-specs-with-shared-behavior/

      【讨论】:

      • 您的博文非常不完整。首先,它错过了你在那里谈论的sharedBehaviorForGameOf ,其次,我有一个测试规范文件,它几乎是你的 100% 的副本,即使是精确的层次结构,每个 @987654324 只有一个 it() 块@块,我的“共享”变量仅对我的第一个测试可见,并且在第一个测试以下的任何其他测试中都不可引用。如果你完成你的文章并提供一些关于共享变量/函数的提示,我想很少有人像我这样会感激。除此之外,你在图书馆做得很好,我喜欢它。
      • 忘了提到我正在尝试使用runs() 块中的共享变量,这些变量消耗了真实(非模拟)AJAX 调用的结果。也许这是一个范围问题,因为显然您的香草示例效果很好。
      【解决方案3】:

      我发现shared examples from thoughtbot 上的文章非常有用。

      我在coffeescript中实现如下:

      1) 在所有规范文件之前加载的一些帮助文件中:

      window.FooSpec =
        sharedExamples: {}
      
      window.itShouldBehaveLike = (->
        exampleName      = _.first(arguments)
        exampleArguments =
          _.select(_.rest(arguments), ((arg) => return !_.isFunction(arg)))
        innerBlock       = _.detect(arguments, ((arg) => return _.isFunction(arg)))
        exampleGroup     = FooSpec.sharedExamples[exampleName]
      
        if(exampleGroup)
          return describe(exampleName, (->
            exampleGroup.apply(this, exampleArguments)
            if(innerBlock) then innerBlock()
            )
          )
        else
          return it("cannot find shared behavior: '" + exampleName + "'", (->
            expect(false).toEqual(true)
            )
          )
      )
      

      2) 对于我的规格:

      (a) 我可以定义共享行为:

      FooSpec.sharedExamples["had a good day"] = (->
        it "finds good code examples", ->
            expect(this.thoughtbot_spy).toHaveBeenCalled()
      )
      

      (b) 并在某些规范中的任何地方使用它:

      itShouldBehaveLike("had a good day")
      

      (注意:我假设规范在上述行之前相应地定义了this.thoughtbot_spy

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-10-10
        • 1970-01-01
        • 2012-01-24
        • 2023-03-23
        • 2012-08-13
        相关资源
        最近更新 更多