5

Coffeescript にクラスがあるとします。

class MyGame
   constructor: () ->
      @me = new Player
      @opponents = [new Player, new Player]

ジャスミンでテストしたい:

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

@次のような演算子を使用して、coffeescript クラスを定義してみてください。

class @MyGame
   constructor: () ->
      @me = new Player
      @opponents = [new Player, new Player]

これにより、ジャスミン テストなど、どこからでもクラスにアクセスできるようになります。また、テスト変数をウィンドウにアタッチする必要がなくなります。

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

すべてのバックボーン クラスの前に @ 記号を使用してコードの名前空間を変更することを受け入れる気はなかったので、さらに掘り下げた結果、うまくいった解決策は、spec/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.coffeejquery.jsましたapp/assets/javascriptsspec/javascripts/helpersspec.js.coffeeのコンテンツのように配置する必要があると思うので、これは最善の解決策ではないかもしれません#=require_tree ./

これはあまりエレガントではないことは承知していますが、同じ状況にある他の人を助けるかもしれません。@Thilo ご意見ありがとうございます。

于 2011-11-03T12:55:49.113 に答える