5

假设我在 Coffeescript 有一堂课:

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但我想这与 Coffeescript 的包装方式有关?

更新:这个问题看起来更像是一个参考问题,如上所述。我正在跑步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所以我认为它要么是 Rails 3.1 资产管道的东西,要么是 Coffeescript 包装对象的方式。

4

4 回答 4

8

尝试使用@运算符定义您的咖啡脚本类,如下所示:

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(即窗口)上,从而允许您根据需要实例化您的类。你现在可能在你的全局空间里有一些全局变量,你的类,但对我来说这是一个不错的权衡。希望这可以帮助!

于 2012-02-10T19:58:32.780 回答
4

我不愿意接受通过在所有主干类前面使用 @ 符号来修改代码的命名空间,所以我挖掘了更多内容,对我有用的解决方案是在我的规范/javascripts 中要求应用程序文件/spec.js.coffee 文件

#= require application
于 2012-06-24T13:35:05.523 回答
1
window.game = () -> new MyGame

这将分配一个将新的 MyGame 返回给 window.game 的函数。您不只是直接想要新实例吗?

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
于 2011-11-03T07:43:04.377 回答
0

例如,我通过定义每个类来解决这个问题class window.MyGame#= require my_file_name在我放在顶部的规范文件中。

jasminerice.js.coffee此外,我将和都放在jquery.jsapp/assets/javascripts. 这可能不是最好的解决方案,因为我认为它们应该spec/javascripts/helpers按照我spec.js.coffee的内容放置#=require_tree ./

我知道这不是很优雅,但它可能会帮助处于相同情况的其他人。@Thilo 感谢您的投入。

于 2011-11-03T12:55:49.113 回答