简体   繁体   English

Jasmine与coffeescript分享了规范范围问题

[英]Jasmine shared specs scoping issues with coffeescript

I'm attempting to DRY up some jasmine tests by extracting out shared examples. 我试图通过提取共享示例来干掉一些茉莉花测试。

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

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


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

This works nicely when everything is defined in one file. 当一切都在一个文件中定义时,这很好用。 The problems I'm encountering occur when I try to move the sharedExamples to a separate file. 当我尝试将sharedExamples移动到单独的文件时,遇到了我遇到的问题。 I get Can't find variable: sharedExamplesForThing ... 我得到Can't find variable: sharedExamplesForThing ...

So in the interest of debugging, I tried the following: 所以为了调试,我尝试了以下方法:

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

In the is acting like a meany block, the log shows sharedExamplesForThing as [Function] but I still get the Can't find variable outside the it . is acting like a meany块一样,日志显示sharedExamplesForThing[Function]但我仍然在it之外得到Can't find variable I feel like this might have something to do with a scoping issue outside of my current experience, but I could be completely wrong about that. 我觉得这可能与我目前的经验之外的范围问题有关,但我可能完全错了。 What am I missing here? 我在这里错过了什么?

(using rails, jasminerice, guard-jasmine) (使用rails,jasminerice,guard-jasmine)

I found the piece on shared examples from thoughtbot really useful. 我发现thinkbot的共享示例中的这篇文章非常有用。

I implemented it in coffeescript as follows: 我在coffeescript中实现了如下:

1) In some helper file that is loaded before all spec files: 1)在所有spec文件之前加载的一些帮助文件中:

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) For my specs: 2)对于我的规格:

(a) I can define a shared behaviour: (a)我可以定义共享行为:

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

(b) And use it anywhere in some spec as: (b)并在某些规范的任何地方使用它:

itShouldBehaveLike("had a good day")

(Note: I am assuming the spec has defined this.thoughtbot_spy accordingly before the above line) (注意:我假设规范已在上述行之前相应地定义了this.thoughtbot_spy

When you assign a top-level member variable in CoffeeScript it is assigned as a property of the global object ( window in a Browser). 在CoffeeScript中分配顶级成员变量时,它将被指定为全局对象(浏览器中的window )的属性。 So it generates the following JavaScript: 所以它生成以下JavaScript:

window.sharedExamplesForThing = ...;

That means that you can refer to it outside the file as window.sharedExamplesForThing or just sharedExamplesForThing . 这意味着您可以在文件外部将其引用为window.sharedExamplesForThing或仅仅是sharedExamplesForThing So what you are doing should work assuming the shared example file has been loaded before the spec file. 所以你正在做的事情应该假设共享的示例文件已经在spec文件之前加载。 I think the problem you have having is that the spec file is loaded first (because describe functions are run as the file is loaded whereas it functions are run after all the files have loaded). 我认为你遇到的问题是首先加载spec文件(因为在加载文件时运行describe函数,而在加载所有文件后运行它的函数)。 So you might need to adjust the load order, you could try putting your shared examples files in a support directory and then requiring this first. 因此,您可能需要调整加载顺序,您可以尝试将共享示例文件放在support目录中,然后首先要求它。

Rather than assigning variables directly to the window object it may be better to set up a namespace to export your shared variables into (so that you don't clutter the global object): 不是直接将变量分配给窗口对象,而是设置命名空间以将共享变量导出到最好(这样就不会使全局对象混乱):

window.MyNamespace = {}

MyNamespace.sharedExamplesForThing = ...

Then in your spec file you can refer to it as MyNamespace.sharedExamplesForThing . 然后在您的spec文件中,您可以将其称为MyNamespace.sharedExamplesForThing

I find it helpful to look at the generated JavaScript to try to understand how CoffeeScript exports variables between files. 我发现查看生成的JavaScript以尝试理解CoffeeScript如何在文件之间导出变量很有帮助。

Here's the blog post I wrote about how best to do shared examples. 这是我写的关于如何最好地做共享示例的博客文章。 Hope this helps. 希望这可以帮助。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM