假设我在Coffeescrapt:中有一个类
class MyGame
constructor: () ->
@me = new Player
@opponents = [new Player, new Player]
哪个想在Jasmine中测试:
describe "MyGame", ->
beforeEach ->
window.game = new MyGame
it "should have two players", ->
expect(window.game.opponents.length).toEqual 2
但是我得到了错误TypeError: Result of expression 'window.game.opponents' [undefined] is not an object.
?
window.game
的方法对我来说也很尴尬。如果我试图将其定义为@game = new MyGame
,我会得到错误ReferenceError: Can't find variable: MyGame
,但我想这与Coffeescapet的包装方式有关?
更新:这个问题看起来更像是上面描述的一个参考问题。我用guard-jasmine
运行,它看起来像
guard 'jasmine', :all_on_start => false, :all_after_pass => false do
watch(%r{app/assets/javascripts/(.+).(js.coffee|js)}) { |m| "spec/javascripts/#{m[1]}_spec.#{m[2]}" }
watch(%r{spec/javascripts/(.+)_spec.(js.coffee|js)}) { |m| "spec/javascripts/#{m[1]}_spec.#{m[2]}" }
watch(%r{spec/javascripts/spec.(js.coffee|js)}) { "spec/javascripts" }
end
我的jasmine.yml
文件有:
src_files:
- "app/assets/**/*.js"
- "app/assets/**/*.coffee"
spec_files:
- '**/*[sS]pec.js.coffee'
asset_pipeline_paths:
- app/assets
- spec/javascripts
我得到了一个ReferenceError: Can't find variable: MyGame
,所以我认为它要么是Rails3.1资产管道的东西,要么是Coffeescapet包装对象的方式。
尝试使用@
运算符定义coffeescript类,如下所示:
class @MyGame
constructor: () ->
@me = new Player
@opponents = [new Player, new Player]
这将允许您从任何地方访问类,例如从您的jasmine测试,并且您还可以避免将测试变量附加到窗口:
describe "MyGame", ->
beforeEach ->
@game = new MyGame
it "should have two players", ->
expect(@game.opponents.length).toEqual 2
原因是coffeescript通过将所有内容封装在闭包中来避免引入全局变量。不幸的是,这对于面向对象的代码来说可能是不可取的。使用@
操作符将类定义附加到全局this,即window,从而允许您根据需要实例化类。你现在可能在你的全局空间,你的类中有一些全局变量,但对我来说,这是一个不错的权衡。希望这能有所帮助!
我不愿意接受在所有主干类前面使用@符号来修改代码的名称空间,所以我仔细研究了一些,对我有效的解决方案是要求在我的spec/javascripts/spec.js.coffee文件中使用应用程序文件
#= require application
window.game = () -> new MyGame
这将为window.game分配一个返回新MyGame的函数。你不是直接想要新实例吗?
window.game = new MyGame
window.game方法对我来说也很尴尬。
这个怎么样
describe "MyGame", ->
game = null
beforeEach ->
game = new MyGame
it "should have two players", ->
expect(game.opponents.length).toEqual 2
例如,我通过将每个类定义为class window.MyGame
来解决了这个问题。在规范文件中,我将#= require my_file_name
放在顶部。
此外,我将jasminerice.js.coffee
和jquery.js
都放置在app/assets/javascripts
中。这可能不是最好的解决方案,因为我认为它们应该放在spec/javascripts/helpers
中,因为我的spec.js.coffee
的内容是#=require_tree ./
。
我知道这不是很优雅,但它可能会帮助其他处于同样情况的人@Thilo感谢您的投入。