使用 Jasmine 和 Rails 3.1 测试 Coffeescript
Posted
技术标签:
【中文标题】使用 Jasmine 和 Rails 3.1 测试 Coffeescript【英文标题】:Testing Coffeescript with Jasmine and Rails 3.1 【发布时间】:2011-12-20 22:48:53 【问题描述】:假设我在 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(%rapp/assets/javascripts/(.+)\.(js\.coffee|js)) |m| "spec/javascripts/#m[1]_spec.#m[2]"
watch(%rspec/javascripts/(.+)_spec\.(js\.coffee|js)) |m| "spec/javascripts/#m[1]_spec.#m[2]"
watch(%rspec/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 包装对象的方式。
【问题讨论】:
Player
有同样的问题吗?
这只是 Jasmine 的问题吗?网站的代码怎么样?另外,也许这有帮助:***.com/questions/6150455/…
【参考方案1】:
尝试使用 @
运算符定义您的咖啡脚本类:
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(即窗口),从而允许您根据需要实例化您的类。你现在可能在你的全球空间里有一些全球变量,你的课程,但对我来说这是一个不错的权衡。希望这会有所帮助!
【讨论】:
感谢您的跟进。这当然是最好的解决方案,也是我最终要做的。【参考方案2】:我不愿意接受通过在所有主干类前面使用 @ 符号来修改代码的命名空间,所以我挖掘了更多内容,对我有用的解决方案是在我的spec/javascripts/spec.js.coffee 文件
#= require application
【讨论】:
虽然这可以工作,但它似乎......对于单元测试来说是笨拙的。并非所有测试都需要应用程序清单所需的每个 js 文件。 IMO,您应该只需要每次测试所需的文件。【参考方案3】: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
【讨论】:
在这种情况下,我得到一个ReferenceError: Can't find variable: MyGame
。顺便提一句。我正在使用 Rails 3.1,我的 jasmine.yml
有 src_files: - "app/assets/**/*.js" - "app/assets/**/*.coffee"
和资产管道设置正确。
MyGame 如何对测试文件(或一般外部世界)可见?不幸的是,没有真正的标准,我不能代表 Rails。我使用 CommonJS,我会在文件顶部有MyGame = require 'models/game'
。但我不知道这是否适用于您的设置。
我已经更新了这个问题。正如您所描述的,我认为这更像是一个参考问题,我猜它与 Rails 3.1 资产管道有关。【参考方案4】:
例如,我通过将每个类定义为class window.MyGame
来解决了这个问题。在规范文件中,我将#= require my_file_name
放在顶部。
此外,我将jasminerice.js.coffee
和jquery.js
都放在了app/assets/javascripts
中。这可能不是最好的解决方案,因为我认为它们应该放在spec/javascripts/helpers
中,因为我的spec.js.coffee
的内容是#=require_tree ./
。
我知道这不是很优雅,但它可能会帮助处于相同情况的其他人。 @Thilo 感谢您的投入。
【讨论】:
以上是关于使用 Jasmine 和 Rails 3.1 测试 Coffeescript的主要内容,如果未能解决你的问题,请参考以下文章
Ruby on Rails 5.1 和 Vue.js 2.4.x – 使用 Karma、Jasmine 进行测试 – 如何安装?
基于karma和jasmine的Angularjs 单元测试
Angularjs 基于karma和jasmine的单元测试