Jasmine 与咖啡脚本共享规范范围问题
Posted
技术标签:
【中文标题】Jasmine 与咖啡脚本共享规范范围问题【英文标题】:Jasmine shared specs scoping issues with coffeescript 【发布时间】: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)
【问题讨论】:
【参考方案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
)
【讨论】:
以上是关于Jasmine 与咖啡脚本共享规范范围问题的主要内容,如果未能解决你的问题,请参考以下文章
在 CoffeeScript 文件上运行 Jasmine 测试时对象未定义错误
Jasmine:Angular Typescript 项目中的“不完整:未找到规范”