6

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. I get 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. 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)

4

3 回答 3

2

我发现关于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在上述行之前已相应定义)

于 2013-04-28T00:39:32.737 回答
1

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

window.sharedExamplesForThing = ...;

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

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

window.MyNamespace = {}

MyNamespace.sharedExamplesForThing = ...

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

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

于 2013-03-01T19:59:09.127 回答
0

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

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

于 2013-03-05T19:07:05.413 回答