2013-03-01 53 views
6

我試圖通過提取出共享示例來幹掉一些茉莉花測試。Jasmine與coffeescript共享規格範圍問題

@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],但我仍然得到Can't find variableit之外。我覺得這可能與我目前的經驗之外的範圍問題有關,但我可能完全錯誤。我在這裏錯過了什麼?

(使用導軌,jasminerice,護茉莉)

回答

1

當分配在CoffeeScript中它被指定爲全局對象(window在一個瀏覽器)的性質的頂層成員變量。因此,它會生成以下的JavaScript:

window.sharedExamplesForThing = ...; 

這意味着,你可以參考它的文件之外爲window.sharedExamplesForThing或只是sharedExamplesForThing。因此,假設共享示例文件已經加載到spec文件之前,您應該如何工作。我認爲你遇到的問題是spec文件首先被加載(因爲描述函數是在文件被加載時運行的,而它的函數是在所有文件加載後運行的)。因此,您可能需要調整加載順序,您可以嘗試將您的共享示例文件放在support目錄中,然後首先要求。

而不是直接分配變量到窗口對象,可能是更好的建立一個命名空間的共享變量導出到(讓你不擾亂全局對象):在

window.MyNamespace = {} 

MyNamespace.sharedExamplesForThing = ... 

然後你的規格文件你可以參考它MyNamespace.sharedExamplesForThing

我發現查看生成的JavaScript有助於理解CoffeeScript如何在文件之間導出變量。

0

這是我寫的關於如何最好地做共享示例的博文。希望這可以幫助。

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

+0

你的博客文章是非常不完整的。首先,它忽略了你正在討論的'sharedBehaviorForGameOf',其次,我有一個測試規範文件,幾乎是你的100%副本,甚至到了確切的層次結構,並且每個文件只有一個「 'describe()'塊,仍然,我的「共享」變量只對我的第一個測試可見,並且它們在第一個測試下面的任何其他測試中都是不可引用的。我認爲,如果你完成你的文章,並給出關於共享變量/函數的一些提示,像我這樣的人會很感激。除此之外,你在圖書館做得很好,我喜歡它。 – dimitarvp 2013-04-18 18:58:08

+0

忘了提及我正在嘗試使用'runs()'塊中的共享變量,這些變量消耗了真實(非模擬)AJAX調用的結果。也許這是一個範圍問題,因爲顯然你的香草實例工作得很好。 – dimitarvp 2013-04-18 19:14:51

2

我發現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